React setStateデータ更新メカニズムの詳細な説明

React setStateデータ更新メカニズムの詳細な説明

setStateを使用する理由

React 開発のプロセスでは、コンポーネントの状態を処理することが不可欠です。 React を使用したことがある人なら誰でも、状態の値を変更する場合は、内部的に提供される setState メソッドを使用する必要があることを知っています。割り当てを使用して状態の値を直接変更できないのはなぜですか?まずは分析してデモを見てみましょう。

クラス Index は React.Component を拡張します {
  この状態 = {
    カウント: 0
  }
  クリック時 = () => {
    this.setState({
       カウント: 10
    })
  }
  与える() {
    戻る (
      <div>
        <span>{this.state.count}</span>
        <button onClick={this.onClick}>クリック</button>
      </div>
    )
  }
}

上記のコードによれば、ボタンをクリックすると、state の count の値が 10 に変更されることがわかります。ページの表示を更新します。したがって、状態の変更には、対応する値の変更とページの更新という 2 つの効果があります。 **これら 2 つのポイントを実現するには、React で setState が必要です。 onClick メソッドの内容をthis.state.count = 10に変更し、メソッド内でthis.stateの値を出力すると、state の値が変更されたことがわかります。しかし、ページは最新の値に更新されません。 ☆まとめ:

  • 状態値を変更する目的は、ページを更新することです。React が最新の状態を使用してページをレンダリングすることを期待します。ただし、直接割り当て方式では、React は状態の変化を監視できません。
  • 状態データが変更したことを React に通知するには、setState メソッドを使用する必要があります。

☆拡大するには:

Vue では、データの更新に直接割り当てが使用され、Vue は最新のデータを使用してページをレンダリングすることもできます。これはなぜでしょうか? vue2 では、データの変更を監視するために、Object.defineProperty() を使用してデータの get メソッドと set メソッドを監視します。vue3 では、データの変更を監視するために ES6 プロキシが使用されます。

setStateの使用法

setState の使い方は皆さんご存知だと思いますが、ここでも記録しておきます。setState メソッドには 2 つのパラメーターがあります。最初のパラメーターは、プロパティ値を直接変更するオブジェクトにすることも、以前の状態値を取得できる関数にすることもできます。 2 番目のパラメータは、最新の状態値を取得できるオプションのコールバック関数です。コールバック関数は、コンポーネントの更新が完了した後に実行されます。これは、 componentDidUpdateライフサイクル中に実行されるのと同じです。

  • 最初のパラメータがオブジェクトの場合: 上記のデモと同様に、stateの属性値を直接変更します。
this.setState({
	キー:newState
})
  • 最初のパラメータが関数の場合: 関数内で前の状態のプロパティ値を取得できます。
// prevState は前の状態、props はこの更新が適用されたときのプロパティです
this.setState((前の状態、props) => {
  戻る {
      キー: prevState.key 
  }
})

非同期または同期更新

setState() はコンポーネントの状態の変更をキューに入れて、このコンポーネントとその子を更新された状態で再レンダリングする必要があることを React に通知します。これは、イベント ハンドラーとサーバー データに応答してユーザー インターフェイスを更新する主な方法です。setState() を、コンポーネントを更新するための即時コマンドではなく、要求として扱います。パフォーマンスをより良く認識するために、React はこれを遅延呼び出しし、1 回のパスで複数のコンポーネントを更新します。 React は状態の変更がすぐに有効になることを保証しません。

まずは上記のコードを修正してみましょう。前述のように、onClick メソッドで setState が 3 回連続して呼び出される場合、setState は非同期メソッドです。各呼び出しでは、変更がキューに追加されるだけです。同期的に呼び出すと、最後の更新のみが実行されるため、結果は 3 ではなく 1 になります。

クリック時 = () => {
  const { count } = this.state
  this.setState({ count: count + 1 })
  this.setState({ count: count + 1 })
  this.setState({ count: count + 1 })
}

上記のコードはObject.assign()メソッドとして理解できます。

オブジェクト.assign()
  州、
  { カウント: 状態.count + 1 },
  { カウント: 状態.count + 1 },
  { カウント: 状態数 + 1 }
)

関数が最初のパラメータとして渡され、3 回連続して呼び出された場合、結果はオブジェクトとして渡した場合と同じになりますか?

クリック時 = () => {
  this.setState((前の状態、props) => {
    戻る {
      カウント: prevState.count + 1
    }
  })
  this.setState((前の状態、props) => {
    戻る {
      カウント: prevState.count + 1
    }
  })
  this.setState((前の状態、props) => {
    戻る {
      カウント: prevState.count + 1
    }
  })
}

オブジェクトを渡す方法とは全く異なる結果になります。関数メソッドを使用すると、3 増加の効果が得られます。これはなぜでしょうか? 関数内で最新の状態とプロパティの値を取得できます。上記から、setState がバッチで更新されていることがわかります。関数を使用すると、現在の状態が以前の状態に基づいていることが保証されるため、3 ずつ自己増加させる効果が得られます。

☆まとめ: setState メソッドが非同期なのはなぜでしょうか?

  • パフォーマンスを大幅に向上できます。React16 では、タスクを分割して優先順位を付け、優先度の高いタスクを優先する Fiber アーキテクチャが導入されました。ページの応答は優先度の高いタスクであるため、setState が同期の場合、ページが更新されるとすぐに更新する必要があり、ページの応答がブロックされます。最善のアプローチは、複数の更新を取得してからバッチ更新を実行することです。ページを一度だけ更新します。
  • 状態が同期的に更新されても、レンダリング関数がまだ実行されていない場合、状態とプロパティを同期させることはできません。

**すべての setStates は非同期ですか? **答えはイエスです! ! ! React で setState が同期されるシナリオもあります。

クリック時 = () => {
	this.setState({ count: this.state.count + 1 })
  コンソールログ(この状態)
  タイムアウトを設定する(() => {
    this.setState({ count: this.state.count + 1 })
    コンソールログ(この状態)
  }, 0)
}

上記のコードは **0, 2 を出力します。 **これはなぜでしょうか?実際、React の setState は厳密な意味では非同期関数ではありません。これはキューの遅延実行を通じて実装されます。 isBatchingUpdatesを使用して、現在の setState が更新キューに追加されるか、ページが更新されるかを決定します。 isBatchingUpdates=tureの場合は更新キューに追加し、それ以外の場合は更新を実行します。

React はisBatchingUpdatesを使用して更新キューに参加するかどうかを決定することがわかっています。では、なぜsetTimeoutイベントでisBatchingUpdates値がfalseいるのでしょうか? その理由は、React では HTML のネイティブ イベントがカプセル化され、合成イベントと呼ばれるためです。 **そのため、React 独自のライフサイクルや合成イベントでは、 isBatchingUdatesの値を制御し、その値を使用してページを更新するかどうかを判断できます。ホスト環境によって提供されるネイティブ イベント (つまり、非合成イベント) では、 isBatchingUpdatesの値を false に設定できないため、更新はすぐに実行されます。

☆setStateは同期シナリオではありませんが、特別なシナリオではReactによって制御されません**

要約する

setState は単純な同期関数でも非同期関数でもありません。同期と非同期のパフォーマンスの違いは、呼び出しシナリオの違いに反映されます。これは、React のライフサイクルおよび合成イベント内で非同期関数として動作します。 DOM のネイティブ イベントなどの非合成イベントでは、同期関数として表示されます。

以上がReact setStateデータ更新メカニズムの詳細な説明です。React setStateデータ更新メカニズムの詳細については、123WORDPRESS.COMの他の関連記事に注目してください。

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

<<:  JDBC が MySQL に接続して中国語を処理するときに文字化けする問題の解決方法の詳細説明

>>:  Ubuntu 18.04 向け VMware Tools のインストールと構成のチュートリアル

推薦する

プレフィックスケースを削除する Nginx リバース プロキシ構成のチュートリアル

nginx をリバース プロキシとして使用する場合、リクエストをそのまま次のサービスに転送するだけで...

VUE のコンパイル スコープとスロット スコープのスロットの問題について

スロットとは何ですか?スロット ディレクティブは v-slot であり、現在 slot と slot...

Nexus をベースに Alibaba Cloud プロキシ ウェアハウスを構成するプロセスの分析

Nexus のデフォルトのリモートリポジトリは https://repo1.maven.org/ma...

Centos6にMysql5.7をインストールする方法

環境セントロス6.6 MySQL 5.7インストールシステムがインストールされている場合は、まずアン...

IE8 互換性について: X-UA-compatible 属性の説明

問題の説明:コードをコピーコードは次のとおりです。 <meta http-equiv=&quo...

要素動的ルーティングブレッドクラムの実装例

マスターするには: localStorage、コンポーネントのカプセル化えーと、GIF に変換したビ...

MySQL トリガーの使用方法と利点と欠点の紹介

目次序文1. トリガーの概要2. トリガーの作成2.1 トリガー構文の作成2.2 コード例3. トリ...

Xampp サーバーで MySQL パスワードを変更する方法 (画像付き)

今日、PHP で作業しているときに、Xampp サーバーに付属の mysql データベースを使用する...

CSS3で実装されたサムネイルホバー効果

成果を達成する実装コードhtml <ヘッダー> <h1><em>...

HTML における要素の水平および垂直中央揃えに関する議論

ページをデザインするときには、ログイン ウィンドウを中央に配置するなど、DIV を中央に配置し、ペー...

HTML ボディタグと HTML でよく使われる制御タグの詳細な説明

1. <body> タグ: Web ページの本体をマークするために使用されます。body...

jsを使用して簡単なスネークゲームを書く

この記事では、参考までに、jsで書かれたシンプルなスネークゲームの具体的なコードを紹介します。具体的...

Docker-compose インストール db2 データベース操作

db2 データベースをホストマシンに直接インストールするのは面倒で、ユーザーや権限を巻き込むのも不便...

Linux 7.6 バイナリに MySQL 8.0.27 をインストールする詳細な手順

目次1. 環境整備1.1 オペレーティング システムのバージョン1.2 ディスク容量1.3 ファイア...