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年間のユーザーエクスペリエンス

推薦する

MySQL インデックス プッシュダウンの詳細

目次1. 左端接頭辞原則2. 表に戻る3. インデックスプッシュダウン序文:インデックス プッシュダ...

WIN10 での JDK インストールと環境変数の設定手順 (詳細版)

目次1. JDKをダウンロードする(例としてjdk1.8.0を使用する) 2. JDK をインストー...

JS の new 関数の詳細な説明

目次1. 例2. 兵士100人を作成する3. 質問4. 改善点5. エレガント? 6. JSの父から...

バッチファイルを処理するLinuxの1行コマンドの詳細な説明

序文最良の方法は、あなたが思いつく最も速い方法ではないかもしれません。職場で一時的に使用するスクリプ...

VUE+Canvasは、インゴットを受け取る富の神のゲームを実装します

前回のキャンバス ゲーム シリーズへようこそ: 《VUEがFlappy Birdを実装しました〜〜〜...

Linuxのアラーム機能の例の説明

Linuxアラーム機能の紹介上記のコード: #include <stdio.h> #in...

Mysql で期間の交差をクエリする方法

MySQLクエリ期間の交差使用シナリオデータベース テーブルには、starttime と endti...

VMware インストール後に仮想ネットワーク カードが表示されない問題について

1 問題の説明: 1.1 Windows 10 に VMware を初めてインストールする場合、また...

航空機戦争ゲームを実装するためのJavaScript

この記事では、キャンバスとjsを使用して簡単な飛行機戦争を実装する方法を参考までに紹介します。具体的...

ウェブデザインに必須のツール: Firefox Web Developer プラグイン CSS ツールセットのチュートリアル

プラグインは Firefox ブラウザにインストールされます。 Web Developer プラグイ...

HTML テーブル マークアップ チュートリアル (16): タイトルの水平方向の配置属性 ALIGN

デフォルトでは、表のタイトルは水平方向に中央揃えされます。ALIGN 属性を使用して、タイトル テキ...

スマートCSSを使用して、ユーザーのスクロール位置に基づいてスタイルを適用します。

現在のスクロール オフセットを html 要素の属性に追加することで、現在のスクロール位置に基づいて...

JS は複数のタブを切り替えるカルーセルを実装します

カルーセルアニメーションは、ページの外観とインタラクティブなパフォーマンスを向上させることができます...

Navicat for MySQL 15 登録とアクティベーションの詳細なチュートリアル

1. Navicat for MySQL 15をダウンロードするhttps://www.navica...

角丸四角形の HTML+CSS 実装コード

退屈していたので、突然角丸四角形の実装を思いつきました。しかし、私たちはこの話題についてあまりにも長...