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 のインストールと構成のチュートリアル

推薦する

Docker Docker の保存場所を変更する コンテナイメージのサイズ制限を変更する操作

これは新しいバージョンではもう不可能なようで、推奨されません。そうでない場合は、ソフト リンクを直接...

CSS 兄弟要素フローティング分析の概要

float:左/右/なし; 1. 同じレベルフローティング(1)ブロックレベル要素を同じ行に表示する...

バッテリー残量が少なくなったときに Linux を自動シャットダウンする方法

序文最近、私の住居の電力事情が不安定で、突然の停電が頻繁に起こります。ノートパソコンを持っているので...

Vue3 Vue CLI マルチ環境設定

目次1. はじめに2. 切り替え1. 開発および本番環境の設定ファイルを追加する2. 複数の環境をサ...

CSS を使用して波状のウォーターボール効果を実装するためのサンプルコード

今日は新しいCSS特殊効果、波型ウォーターボール効果を学びました。これもとても美しいです HTML:...

React Router 5.1.0 はページジャンプナビゲーションを実装するために useHistory を使用します

目次1. withRouterコンポーネントを使用する2. ルートタグを使用するReactRoute...

MySQLはパスワードなしでログインする例を実装しています

具体的な方法:ステップ1: mysqlサービスを停止する /etc/init.d/mysqld を停...

CentOS 7 はネットワークカードを変更した後、インターネットにアクセスできません

不明なドメイン名 www.baidu.com を Ping するホストのIPアドレスを変更する右クリ...

MySQL における between の境界と範囲の説明

境界範囲間のmysql間の範囲は両側の境界値を含む例: 3 から 7 までの id は、id >...

JSはクリックドロップ効果を実装します

jsはクリックとドロップの特殊効果を実現します。まずは効果画像を見てみましょうさっそく始めましょう。...

VirtualBox を使用して Linux クラスターをシミュレートする方法

1. ホストMacbookにHOSTをセットアップする前回のドキュメントでは仮想マシンの静的 IP ...

MySqlはページクエリ機能を実装します

まず、ページ分割クエリを使用する理由を明確にする必要があります。データが膨大なため、すべてのデータを...

MySQL バージョン 5.7.24 のデータベース インストール プロセスの詳細なグラフィック説明

MySQL は最も人気のあるリレーショナル データベース管理システムです。WEB アプリケーションに...