web-dev-qa-db-ja.com

shouldComponentUpdate内からsetStateを呼び出しても問題ありませんか?

状態変化に応じて、別の状態変化をトリガーしたいと思います。それは本質的に悪い考えですか?

特定の種類のシナリオは、コンポーネントがthis.state.current_stateの値に従ってさまざまな情報をレンダリングするステートマシンとしてモデル化されていることです。しかし、外部イベントは、フラックスストアを介して状態を変更することで、状態遷移を経験するように促すことができます。アイデアを理解するための人為的なシナリオを次に示します。

これを行うための正しいライフサイクルメソッドはshouldComponentUpdateだと思います。この効果に何か:

shouldComponentUpdate: function(nextProps, nextState) {
    if (nextState.counter > 4 && this.state.current_state !== DISPLAY_MANY) {
        this.setState({ current_state: DISPLAY_MANY });
    }
    return true;
}

一部の子コンポーネントでは、counterが増加する場合があるため、counter変数の値に基づいて何が表示されるかを推測するのではなく、状態を明示的にエンコードします。

実際のシナリオはこれよりも複雑ですが、うまくいけば、このシナリオはアイデアを理解するのに十分なほど詳細です。私の考えていることをしても大丈夫ですか?

編集:余分な状態条件を追加することにより無限ループのトリガーを回避するようにコード例を修正

12
osdiab

shouldComponentUpdateは、コンポーネントをまったく更新する必要があるかどうかを特定することを目的としています。次のようなことを行うには:

_if (nextState.counter == this.state.counter && nextProps.foo == this.Props.foo) {
  return false;
}
_

componentWillReceivePropsは、external(props)の変更に応答するためのものです。ドキュメントで指摘されているように、同等のcomponentWillReceiveStateはありません。コンポーネント(およびコンポーネントのみ)は、通常、次の1つ以上のイベントを介して、独自の状態変更をトリガーします。

  • getInitialStateの初期レンダリング
  • componentWillReceivePropsの小道具を更新しました
  • _<input>_フィールドなどでのユーザー操作、たとえばコンポーネントのカスタムonChangeInput()関数内。
  • 変化:リスナーからのストアの変更に応答します。通常、カスタム関数はgetStateFromStores()を呼び出し、状態が更新されます。

私は推測します状態変更を作成するためにコンポーネント内に1つの関数があり、状態が更新される前に介入するために同じコンポーネント内の別の関数があることは意味がありません。

あなたのケースでは、ロジックを(状態を更新する必要があるかどうかを判断するために)ストアの更新を処理するgetStateFromStores()関数に移動できます。
または、単に状態をそのままにして、レンダリング関数を変更し、counter> 4の場合にレンダリングが異なるようにすることもできます。

16
wintvelt

いいえ。代わりにcomponentWillReceivePropsを使用してください。 shouldComponentUpdateと同じ署名があり、そこでthis.setStateを呼び出しても安全です。

9
Tom Chen