{setC1((c)=>c+1);Promise.resolve().then(()=>{setC1((c)=>c+1);});};consthandleClick2=()=>{Promise.resolve().then"> React18 マイクロタスクのバッチ処理の問題-PHP中国語ネットワークQ&A
React18 マイクロタスクのバッチ処理の問題
P粉506963842
P粉506963842 2023-09-07 22:30:24
0
1
443

rree

React18 バージョンでは、handleClickメソッドをクリックすると 2 つのレンダリングが発生するのに、handleClick2メソッドをクリックすると 1 つのレンダリングしか発生しないのはなぜですか?

両方のメソッドの出力を同じにする必要があります。誰かがなぜ違うのか教えてもらえますか?

P粉506963842
P粉506963842

全員に返信 (1)
P粉642920522

これらの呼び出しシーケンスがどのように異なるのか、また観察される動作がどのように起こり得るのかを説明します。

React が内部でどのようにステータスをバッチで更新するのか正確に説明することはできませんが、 私は、React には複雑な最適化があり、React を使用する開発者には無関係であり、React の内部構造の深い理解が必要であり、場合によってはバージョン間の変更さえも必要になると考えています。(お気軽に修正してください。)

###違い###

Promise.resolve()

新しいマイクロタスクを配置します。これは実際にはwindow.queueMicrotask()と同等です。

setState

関数(おそらく)は、新しいマイクロタスクもスケジュールします。 したがって、それらのコールバック (PromisesetState) は同じ実行フェーズで呼び出されます。これら 2 つのバリエーションの違いは次のとおりです。

handleClickA
    では、
  • setState2フックが 2 つのupdater関数の間で呼び出されます。handleClickBでは、2 つの
  • updater
  • 関数が順番に直接呼び出されます。サンプルコード
  • 呼び出しシーケンスをよりわかりやすく説明するために、コードを少し書き直しました。
リーリー

呼び出しシーケンスの説明

ここで呼び出しシーケンスを説明します。

(

FIFO

>):

ハンドルクリックA

リーリー

ハンドルクリックB

リーリー

個人的な解釈React は現在キューに入れられているすべての

updater

関数をバッチ処理しようとしていると思います。

つまり、updater 関数のみが呼び出されるときは常に、それらを一緒にバッチ処理してみてください。および

最終状態を 1 回だけ更新します。ただし、新しいsetState関数が呼び出された場合、React は

現在の更新ループ

を完了し、次のupdater定期関数を呼び出す前に新しいレンダリングを開始する可能性があります。 。なぜこれが行われるのかは推測することしかできません代码> 新しい

setState

が何らかの理由でバッチを壊す可能性があるため、または

    新しい
  • setState呼び出しが再帰的に行われると、次のレンダリングが大幅に遅延するか、
  • React の担当者は、最適な最適化戦略とそのトレードオフをまだ模索中です。
  • (...またはこれはバグです。)
いいねを押す+0
    最新のダウンロード
    詳細>
    ウェブエフェクト
    公式サイト
    サイト素材
    フロントエンドテンプレート
    私たちについて 免責事項 Sitemap
    PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!