ReactNativeで renderメソッドにonpress={this.setState{…}}は何でダメなのか?

質問サイトで、こんな質問がありました。

「ReactNativeで renderメソッドにonpress={this.setState{…}}になっている場合、

画面が真っ白になり、componentが表示されない。

onPress={this.setState({isModalVisible: true})}

このような記述になっていると、setStateがひたすら呼ばれています、consoleを確認したところ、それと同時にrenderメソッドが呼ばれていた模様。そもそも何でひたすらsetStateが呼び出されるのか。」

私が、その質問サイトに答えを書きましたが、実はここが重要な基礎にも関わらず、しっかり理解していない方も多いようです。

私自身も同じことをした経験もありますし、タイムチケットで、このような質問もありました。


やはり、みんな共通して認識の曖昧なところかもしれませんので

ここで記事にまとめてみました。

回答


renderメソッドはReact Nativeの管理下に置かれています。
我々何もしなくても、ReactNativeが勝手に必要なとき、renderメソッドを呼び出します。
何らかの変化があったら、renderメソッドは呼び出されます。


Buttonとかのコンポーネントの仕様書を見る限り
onPress=の後ろはFunctionが来ることになっています。
つまり

onPress={() =>  {this.setState({isModalVisible: true})}}

が正しいです。
こうすることによって、Buttonが押された時に実行されるべきFunctionをReactNativeに教えます。ReactNativeは約束通りにやることをやります。

() =>  {this.setState({isModalVisible: true})}

イコール

function myFunc(){
    this.setState({isModalVisible: true})
}

ここで、ボタンを押したら実行する関数なので名前がなくてもいいので、()=>{}という形になっています。

では、なぜ

onPress={this.setState({isModalVisible: true})}

がダメなのかと言いますと(私の理解で言語化してみますが)
ここは関数ではなく、評価式です。
{}の中の部分は普通にプログラムの一部として、ReactNativeがrenderメソッドの中に遭遇したら、即実行します。
例えば、<View style={styles.container}>のように
{}の部分は、実際に「プログラム」として実行され、実行の結果として具体的なstyleを取って来ることになります。

onPress={this.setState({isModalVisible: true})}

ですと、「押されたら、これを実行してね」になっていないからです。
①で説明したように、上は「評価式で、ただのプログラム」ですから、renderメソッドに入っていて、一回実行されると、何か変化したこと(setStateしたから)になって、またrenderメソッドが実行され、その次も、その次もと無限ループになります。

まとめ

いかがでしょうか?

実は、ここがうっかりミスした場合が結構多くて

これからは、onPressのところではしっかり関数を設定してあげるようにしましょう。

あと、補足ですが、render()メソッドには、onPressのところだけではなく、this.setState()は避けたほうがいいですね。this.setStateを使うと、上記のように無限ループになります。

ではまた!

[amazonjs asin=”B078KDYXSG” locale=”JP” title=”React Nativeで初めるiOS・Androidクロスプラットフォームアプリ開発入門 – その1”]

2018年 React Nativeで真剣なアプリを開発するなら、絶対使うライブラリー!

Add a Comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close