React で複数の setStates が何回呼び出されるのでしょうか?

React で複数の setStates が何回呼び出されるのでしょうか?

1. 2 つの setState を何回呼び出すのですか?

次のコードに示すように、 statecountが存在します。ボタンにクリック イベントがバインドされ、イベント内でsetState 2 回実行され、そのたびにcountの値が1ずつ増加します。

ボタンをクリックすると、 setStateは何回実行されますか? render()何回実行されますか?

回答:各1回。

状態 = { カウント: 0 };
ハンドルクリック = () => {
    this.setState({ count: this.state.count + 1 });
    this.setState({ count: this.state.count + 1 });
};
与える() {
    console.log(`レンダリング`);
    戻る (
        <>
            <div>現在のカウント: {this.state.count}</div>
            <button onClick={this.handleClick}>追加</button>
        </>
    );
}

常識的に考えると、ボタンが初めてクリックされたとき、 setState 2 回実行されるため、 countの値は毎回1ずつ増加し、 render() 2 回実行され、最終的なcountの値は 2 になるはずです。しかし、React はそうは動作しません。

ブラウザで上記のコードを実行するだけです:

最初、ページにはcountの値が0であることが示され、コンソールには React が初めてレンダリングするときに出力されるrenderが出力されます。ボタンをクリックすると、ページにはcount値が1であることが表示され、 render 1だけ印刷されます。これは、React がこのプロセス中にsetState 1 回だけ実行し、 render() 1 回だけ実行したことを意味します。

その理由は、React が複数のsetState同じイベント応答関数内で内部的にマージし、 setState呼び出しの回数を減らすことでレンダリング回数を減らし、パフォーマンスを向上させることができるためです。

これは、上記のコードでcountの最終値が1なる理由も説明しています。React は 2 つのsetStateをマージし、最後に1だけ実行し、 render()も 1 回だけ実行されたためです。

2. 2 つの setState のうち、どちらが呼び出されますか?

しかし、上記のコードでは、React がマージされた後にどのsetStateが実行されるかは検証されません。次のコードに示すように、2 番目のsetStatecountの操作を変更して2追加し、残りのコードは変更しません。

状態 = { カウント: 0 };
ハンドルクリック = () => {
    this.setState({ count: this.state.count + 1 });
    this.setState({ count: this.state.count + 2 }); // +2 に変更
};
与える() {
    console.log(`レンダリング`);
    戻る (
        <>
            <div>現在のカウント: {this.state.count}</div>
            <button onClick={this.handleClick}>追加</button>
        </>
    );
}

ブラウザでもう一度実行します。

結果は、ボタンをクリックした後、 countの値が最終的に2になることを示しています。これは、 +2演算が実行され、 render()1だけ実行されることを意味します。つまり、React が複数のsetStateをマージするときに、同じ名前の属性がある場合、同じ名前の後続の属性によって、同じ名前の前者の属性が上書きされます。同じ名前の属性の場合、最後のsetStateの属性が最終的に実行されることがわかります。

3. setTimeout に 2 つの setState が配置されていますか?

クリック イベント関数にタイマーsetTimeoutを追加し、タイマー内でsetState操作を 2 回実行すると、結果はどうなるでしょうか?次のコードでは、イベント処理関数にタイマーsetTimeoutが記述され、 2 つのsetStatesetTimeoutに配置されます。

状態 = { カウント: 0 };
ハンドルクリック = () => {
    タイムアウトを設定する(() => {
        this.setState({ count: this.state.count + 1 });
        this.setState({ count: this.state.count + 2 });
    }, 0);
};
与える() {
    console.log(`レンダリング`);
    戻る (
        <>
            <div>現在のカウント: {this.state.count}</div>
            <button onClick={this.handleClick}>追加</button>
        </>
    );
}

実行結果:

結果は、ボタンをクリックした後、 countの値が最終的に3になり、 +1+2の両方の操作が実行され、 render()2実行されることを示しています。

これは、React の合成イベントおよびライフサイクル関数setState直接呼び出すと、React のパフォーマンス最適化メカニズムによって管理され、複数のsetStateがマージされるためです。ネイティブイベントおよびsetTimeoutでのsetStateの呼び出しは React によって管理されないため、複数のsetStateがマージされることはありません。setState setState複数回記述されている場合、 setState複数回呼び出されます。

4. 結論

onChangeonClickなど、React で直接使用されるイベントは、React によってカプセル化されたイベントです。これらは合成イベントであり、React によって管理されます。

React には、合成イベントとライフサイクル関数のパフォーマンス最適化メカニズムがあります。複数のsetStateをマージします。同じ名前の属性が出現した場合、後者の属性が前者の属性を上書きします。

React のパフォーマンス最適化メカニズムをバイパスして、ネイティブイベントまたはsetTimeoutsetStateを使用すると、React によって管理されなくなります。setState setState複数回記述すると、 setStateが複数回呼び出されます。

React で複数の setStates が何回呼び出されるかについてはこれで終了です。React で複数の setStates が何回呼び出されるかの詳細については、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続き閲覧してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • React 純粋関数コンポーネント setState がページ更新を更新しない問題の解決方法
  • React における同期および非同期 setState の問題のコード分析
  • React setStateデータ更新メカニズムの詳細な説明
  • react setStateの詳細な説明
  • ReactでのsetStateの使用と同期と非同期の使用
  • ReactのsetStateコールバック関数の詳細な説明
  • React.setStateを使用する際に注意すべき3つのポイントについて簡単に説明します。
  • ReactのsetStateソースコードの詳細な研究

<<:  すべてのブラウザとの完全な互換性を実現するために最適なプリセットを選択してください

>>:  理論: 2年間のユーザーエクスペリエンス

推薦する

cocoscreatorプレハブの詳しい説明

目次プレハブプレハブの作り方プレハブの役割1. 同じタイプのノードをバッチで作成する2. 特定の時間...

Vue+WebSocket ページでの長時間接続のリアルタイム更新

最近、Vue プロジェクトではデータをリアルタイムで更新する必要があります。折れ線グラフは 1 秒ご...

適応的な幅と高さを持つ9つの正方形グリッドの背景画像の切り取りの分析

<br />幅と高さが適応するオリジナルの 9 グリッド レイアウトをベースに、ネットワ...

Vueバスの簡単な使い方

Vueバスの簡単な使い方シナリオの説明:コンポーネント A にはコンポーネント B と C が含まれ...

Chrome デベロッパー ツールの詳細な紹介 - タイムライン

1. 概要ユーザーは、アクセスする Web アプリケーションがインタラクティブでスムーズに実行される...

Nginx の高同時実行最適化の実践

1. チューニングの必要性​ 私は、どのように書けばいいのか本当に分からないので、共有するために最適...

MySQL 5.7 mysql コマンドラインクライアントの使用コマンドの詳細

MySQL 5.7コマンドを使用するMySQLコマンドラインクライアント1. パスワードを入力してく...

Docker JVM メモリ使用量の表示

1. Docker コンテナのホスト マシンに入り、指定されたイメージを実行しているコンテナ ID ...

Windows Server 2019 のセットアップ方法 (画像とテキスト付き)

1. Windows Server 2019 のインストールVmware に Windows Se...

CocosCreator クラシック エントリー プロジェクト flappybird

目次開発環境ゲームエンジンのコンセプトCocos Creatorについてプロジェクト構造コード編集環...

ウェブデザインの経験とスキルの概要

■ ウェブサイトのテーマ計画 ウェブサイトのテーマが断片化しすぎないように注意してください。一般的に...

Dockerイメージの作成Dockerfileとコミット操作

イメージを構築するイメージを構築するには、主に 2 つの方法があります。実行中のコンテナをイメージに...

aタグのname属性とid属性を使用してページ内を移動する方法

以前はaタグのname属性を使ってジャンプする方法しか知らなかったのですが、idも使えることを今日知...