サイトアイコン KOKENSHAの技術ブログ

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で真剣なアプリを開発するなら、絶対使うライブラリー!

モバイルバージョンを終了