web-dev-qa-db-ja.com

ReactJSのthis.stateとthis.setstateの違いは何ですか?

最初のコードセクションのように、hasSubmitキーの値を変更したい。これはお勧めできません。しかし、2番目のコードは非同期であり、setStateのコールバック関数を使用したくありません。

  • this.statesetStateの違いは何ですか?
  • 状態値hasSubmitをすぐに変更する方法はありますか?

最初のコード:

this.state.hasSubmit = false
this.setState({})
//Code that will use `hasSubmit`.

2番目のコード:

this.setState({
   hasSubmit: false,
});
//Code that will use `hasSubmit`.

追加:

シナリオは次のとおりです。

  1. hasSubmitは、getInitialState()falseを設定します。
  2. hasSubmitボタンをクリックすると、falsesubmitに変わります。
  3. hasSubmitは、送信されるとtrueに変わります。

最初にsubmitをクリックしても問題ありません。hasSubmittrueに設定されます。

しかし、Second asynchronous codeは問題を解決できますが、submitは依然としてhasSubmitのままなので、First Codeを使用すると、2番目のクリックtrueは間違っています。

46
DanielJyc

React docs の内容は次のとおりです。

this.stateを直接変更しないでください。後でsetState()を呼び出すと、行った変更が置き換えられる可能性があります。 this.stateを不変であるかのように扱います。

setState()はすぐにthis.stateを変更しませんが、保留中の状態遷移を作成します。このメソッドを呼び出した後にthis.stateにアクセスすると、既存の値が返される可能性があります。

SetStateの呼び出しの同期操作の保証はなく、パフォーマンス向上のために呼び出しをバッチ処理できます。 setState()で条件付きレンダリングロジックが実装されていない限り、shouldComponentUpdate()は常に再レンダリングをトリガーします。

可変オブジェクトが使用されており、shouldComponentUpdate()でロジックを実装できない場合、新しい状態が前の状態と異なる場合にのみsetState()を呼び出すと、不必要な再レンダリングが回避されます。

APIを設計された方法で使用することは常に賢明です。ドキュメントが状態を変更しないと言っている場合は、状態を変更しない方が良いでしょう。

setState()は技術的に非同期である可能性がありますが、確かに遅くはありません。コンポーネントのrender()関数は、かなり短い順序で呼び出されます。

状態を直接設定することの1つの欠点は、Reactのライフサイクルメソッド-shouldComponentUpdate()componentWillUpdate()componentDidUpdate()-setState()で呼び出される状態遷移に依存することです。状態を直接変更し、空のオブジェクトでsetState()を呼び出すと、これらのメソッドを実装できなくなります。

もう1つは、プログラミングスタイルが悪いことです。 1つのステートメントで2つのステートメントを実行しています。

さらに、ここには実際の利点はありません。どちらの場合も、render()(またはsetState())が呼び出されるまで、forceUpdate()はトリガーされません。

実際にその必要性を説明することなく、これを行う必要があると主張します。おそらく、問題をもう少し詳しく説明したいと思うでしょう。おそらくより良い解決策があります。

フレームワークに反するのではなく、フレームワークを使用するのが最善です。

更新

以下のコメントから:

必要なのは、以下の変更されたhasSubmitを使用することです。

はい、分かりました。将来の状態プロパティをすぐに使用する必要がある場合、最善の策はローカル変数に保存することです。

const hasSubmit = false;

this.setState({
  hasSubmit: hasSubmit
});

if (hasSubmit) { 
  // Code that will use `hasSubmit` ...
50
David L. Walsh

状態を変更する場合react:で再レンダリングをトリガーする 2番目のコードを使用します。

  this.setState({
    hasSubmit: false,
  });

最初のコードの問題/エラー:

  this.state.hasSubmit = false      // Updates state directly: 
                                    // You are not supposed to do this
                                    // except in ES6 constructors
  this.setState({})                 // passes an empty state to react.
                                    // Triggers re-render without mutating state
5
wintvelt

this.setStateは、reactコンポーネントのライフサイクルを維持し、変数を変更するようには見えません(内部的には状態を変更しますが)。そのため、反応サイクルの一方通行のフローは、副作用なしで維持されます。

注意点は、this.setStateを使用するとES6クラスのコンストラクターで機能しないことです。 ES6コンストラクターでは、this.state =ではなくthis.setStateパターンを使用する必要があります

4
Aditya Singh

ドキュメンテーションのアドバイスを決して無視しないでください。執筆時点では、setStateは、setStateと再レンダリングが終了したときのコールバック関数である2番目の引数を許可します。あなたのコードがhasSubmit値をどのように使用するかを私たちに決して提供しないので、hasSubmitが変更されたことを確認したいときに他の誰かがこれを役に立つと思うかもしれません。

3
Sany Liew

最初の例でthis.forceUpdate()を使用して、状態を強制的に更新する必要があります。例えば:

this.state.hasSubmit = false;
this.forceUpdate();

ただし、Reactエンジンのinitネイティブチェック状態メカニズムであるため、強制更新よりも優れているため、this.setStateを使用することをお勧めします。

setState反応なしでthis.stateのパラメーターを直接更新する場合、mecanizmは状態のパラメーターが更新されたことを認識しません。

1
Dmitriy