1. ホーム
  2. javascript

[解決済み] なぜ、コンポーネントの状態を直接変更できないのですか?

2022-09-08 15:19:03

質問

Reactのチュートリアルやドキュメントの警告は で警告しています。 で警告しているように、状態は直接変更されるべきではなく、すべては setState .

なぜ、直接状態を変更してから (同じ関数内で) this.setState({}) をトリガーするだけでは render .

例: 以下のコードは問題なく動作するようです。

const React = require('react');

const App = React.createClass({
  getInitialState: function() {
    return {
      some: {
        rather: {
          deeply: {
            embedded: {
              stuff: 1,
            },
          },
        },
      },
    },
  };
  updateCounter: function () {
    this.state.some.rather.deeply.embedded.stuff++;
    this.setState({}); // just to trigger the render ...
  },
  render: function() {
    return (
      <div>
        Counter value: {this.state.some.rather.deeply.embedded.stuff}
        <br></br>
        <button onClick={this.updateCounter}>Increment</button>
      </div>
    );
  },
});

export default App;

私は規則に従うことに賛成ですが、ReactJSが実際にどのように動作し、何が間違っているのか、または上記のコードで最適ではないのかについて、さらに理解を深めたいと思います。

の下にある注意書きは this.setState ドキュメント は、基本的に二つのゴチャゴチャを識別します。

  1. 状態を直接変異させ、その後に this.setState を呼び出すと、行った変異を置き換える(上書きする?)かもしれません。上記のコードでこれがどのように起こるかはわかりません。
  2. は、その setState は変異する可能性がある this.state を非同期/遅延方式で効果的に変異させることができます。 this.state を呼び出した直後に this.setState を呼んだ直後では、最終的な変異した状態へのアクセスは保証されません。それはわかったのですが、もし this.setState が更新関数の最後の呼び出しであれば問題ありません。

どのように解決するのですか?

のReactドキュメントは setState はこのように言っています。

NEVER 変異させる this.state を呼び出すように、直接 setState() を呼び出すと、行った変異が置き換わる可能性があるからです。扱う this.state をあたかも不変であるかのように扱います。

setState() はすぐに変異しない this.state を変異させるのではなく、保留中の状態遷移を生成します。アクセスする this.state にアクセスすると、既存の値が返される可能性があります。

への呼び出しの同期動作は保証されていません。 setState の呼び出しは同期動作が保証されておらず、性能向上のためにバッチ処理されることがあります。

setState() に条件付きレンダリングロジックが実装されていない限り、常に再レンダリングのトリガーとなります。 shouldComponentUpdate() . ミュータブルオブジェクトが使われていて、そのロジックが shouldComponentUpdate() に実装できない場合は setState() を呼び出すことで、不必要な再レンダリングを避けることができます。

基本的に、もしあなたが this.state を直接修正すると、その修正が上書きされるかもしれない状況を作り出してしまいます。

拡張された質問1)と2)に関連します。 setState() は即時性がない。 への直接的な変更を含まないかもしれない、それが起こっていると考えるものに基づいて、状態遷移を待ちます。 this.state . すぐに適用されるのではなく、キューに入れられるので、その間に何かが変更され、直接の変更が上書きされることは十分にあり得ます。

もし何もなければ、直接の変更ではなく this.state を直接修正しないことは、良い習慣と見なすことができます。あなたのコードが、これらの上書きやその他の問題が起こらないような方法で React と相互作用することを個人的に知っているかもしれませんが、他の開発者や将来の更新が突然奇妙なまたは微妙な問題に気付くことができる状況を作り出しています。