1744059761
2025-04-07 20:28:00
TL; DR:Reactコンポーネントツリーを状態マシンのモデリングとして考えることは、非同期更新とReactの同時機能の意味を明確にするのに役立ちます。
a ステートマシン 時間の経過とともに変化するステートフルシステムを説明する正式な方法です。一般に、システムが存在する可能性がある状態を明示的に定義することと、 状態移行テーブル それは、個別の状態ごとに有効な遷移のセット(マシンを新しい状態に置く更新)を列挙します。
反応アプリケーションは、モデリングと考えることができます ステートマシン。各レンダリングは状態を取り、その状態のUIを生成します。これは有名です UI = f(state) 反応のメンタルモデル。しかし、複雑なアプリケーションの場合、トランジションテーブルを正式に列挙することはしばしば実行不可能です。考えられる状態の数が有限でない場合、テーブルは十分ではなく、代わりに定義する必要があります マッピング:状態を取り入れ、その状態の有効な遷移のセットを返す概念機能。
よく見ると、各Reactアプリケーションは実際にこの関数のバージョンをすでに定義しています。 開発者は、ユーザーがその状態をレンダリングするときにコンポーネントがDOMに結合するイベントハンドラーによって、ユーザーが各州を取得することを有効な一連の移行を暗黙的に定義します。
Reactコンポーネントツリーは定義するだけではないと言えます ui 状態の関数としてだけでなく、定義します 有効な遷移のセット 同じ関数を持つ状態の場合。もっと簡潔に:
{transitions} = f(state)
例えば
TODOアプリは、状態の更新をサポートする可能性があります complete(todoId) 完成したようにTODOをマークします。ユーザーが以前に削除されたTODOを「完了」することはエラーになります。せいぜい、ユーザーにエラーポップアップが表示され、最悪の場合は「TypeError:未定義のプロパティを設定できません」JavaScriptエラーが発生します。州の機械の言葉では、 complete(x) IDのtodoを含まない状態の有効な遷移ではありません x。
Reactプログラミングモデルは、このタイプのエラーを防ぐ直感的な方法を提供します。非常に直感的で、私たちはしばしば考えさえしません 必要です これらの種類のエラーを防ぐため。トリガーする唯一の方法の場合 complete(todoId) 更新は、の「完全」ボタンからのものです コンポーネントは、削除されたときに状態からTODOを削除するだけで、削除されたTODOの「完全な」ボタンをレンダリングしないようにし、ユーザーがこの無効なアップデートをトリガーできないことを保証します。
上記は、JavaScriptがブロッキングUIでシングルスレッドされていることに依存することに注意してください。アプリケーションの状態を同期して更新すると、それを信頼することができます ブラウザがより多くのユーザー入力に屈する前に、最初にこれらの状態の変更をUIにフラッシュします。
非同期更新
非同期の更新により、私たちはこのガードを無料で取得しません。 TODOを削除するには、APIにネットワークリクエストを行う必要がある場合を検討してください。ユーザーがtodoを削除し、アプリケーションの状態を更新するのを待つ場合 後 そのネットワークリクエストが完了すると、削除されたTODOの「完了」ボタンがページ上にレンダリングされ、クリック可能な期間があります。
ユーザーが無効なアップデートを実行しないようにすると、自動的に発生しなくなります。代わりに、いくつかの追加作業が必要ですが、2つの良いオプションがあります。
-
ネットワークリクエストが飛行中にTODOがまったくレンダリングされないようにするために、地元の状態からTODOを楽観的に削除します。
-
ネットワークリクエストが飛行中である間、私たちの州の「保留中」としてTODOをマークし、TODOが保留中に「完全な」ボタンを無効にします。
この楽観的または保留中の状態の更新を同期して洗い流す場合、 {transitions} = f(state) ユーザーが無効な更新をトリガーできないようにしました。
同時更新
たとえば、Reactの同時モード機能の一部 開始承認、意図的に州の更新を実行できるようにします しないでください ユーザーに譲る前にDOMにフラッシュします。非同期の更新と同様に、これにより、UIがユーザーが無効であるとわかっている更新をトリガーできるようにする時間が残ります。
つまり、どの更新プログラムが有効であるかを変更する状態アップデートを実行する場合、同期してフラッシュする楽観的または保留中の更新とペアリングする必要があります。
このため、Reactの同時機能の多くには、 isPending フラグ (usetransition、 USEACTIONSTATE、 usefortatusまたは、優先度の低い更新と組み合わされた楽観的な更新(useoptimistic)。
結論
{transitions} = f(state) ユーザーが無効な更新をトリガーできるようにすることに対して、アプリケーションがどのようにガードされるかを考えるための有用なメンタルモデルです。どの更新が非同期的または同時に安全に適用できるか、どの更新を同期アップデートと組み合わせる必要があるかを明確にして、ユーザーが無効なアクションをトリガーできるようにするために、どの更新を組み合わせる必要があります。また、Reactコンポーネントがこれらの警備員を実施する上で機能する役割を明確にするのに役立ちます。たとえば、状態が保留中の状態にある場合、どのコンポーネントが異なってレンダリングする必要があるかなどです。
この観察につながった会話をしてくれたエヴァン・ヨンに、そしてこの投稿の初期ドラフトを読んでくれたジョー・サヴォナ、ジョーダン・ブラウン、ジャック・ポープ、リック・ハンロンに感謝します。
#transitions #fstate #jordan #eldredge