useSyncExternalStore APIとパラメータ
subscribe、getSnapshot、getServerSnapshotの各引数と、それらが保証すべき条件を学びます。
「useSyncExternalStore APIとパラメータ」はCoddyKit上の無料React Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはReact Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 React Academyコースには全4レッスンが含まれています。
3つの引数の概要
useSyncExternalStoreは、最大3つの引数(subscribe、getSnapshot、そして省略可能なgetServerSnapshot)を受け取ります。これらを組み合わせることで、変更の監視方法と現在の値の読み取り方法をReactに伝えます。
各引数を理解することは重要です。これらの小さなミスが、このフックを使う際にバグを引き起こす最も一般的な原因だからです。
subscribe関数
subscribeはReactからコールバックを受け取り、ストアに登録する必要があります。これにより、ストアが変更されるたびにコールバックが実行されます。また、Reactがクリーンアップ時に呼び出すunsubscribe関数を返す必要があります。
Reactはこれを使って、スナップショットを再読み取りするタイミングを把握します。つまりsubscribeの役割は、変更通知の接続と解除だけです。
getSnapshotは現在の値を返す
getSnapshotはストアの現在の値を返します。Reactはレンダー中にこれを呼び出して状態を読み取り、通知を受け取った後にも呼び出して値が変更されたかどうかを検出します。
特に重要なのは、元のデータが変わっていない場合に、参照的に安定した結果を返すことです。呼び出すたびに新しいオブジェクトを作るのではなく、同じ参照を返す必要があります。
SSR向けのgetServerSnapshot
省略可能なgetServerSnapshotは、サーバーサイドレンダリングと、最初のハイドレーション処理で使用する値を提供します。ブラウザー専用のgetSnapshotが、サーバーには存在しないAPIに依存する場合があるため、これが用意されています。
これを指定すると、クライアントが最初に生成する内容と一致する妥当な値をサーバーに提供できるため、ハイドレーションの不一致を防げます。
戻り値
このフックは現在のスナップショットの値を返します。これは、他の状態と同じようにコンポーネント内で直接使用できます。ストアが変更されるとReactが再レンダーし、フックは更新されたスナップショットを返します。
コンポーネントから見るとリアクティブな状態を読み取っているように扱えますが、信頼できるデータソースは完全にReactの外部にあります。
getSnapshotは同期的で一貫していなければならない
getSnapshotは同期的に実行され、現在のストアの状態だけから導出した値を返さなければなりません。非同期処理を行ったり、同じ元データに対して異なる結果を生成したりしてはいけません。
ReactはgetSnapshotを繰り返し呼び出して結果を比較するため、内部に非決定的な処理や副作用があると、正しく動作しない可能性があります。
不変なスナップショットのパターン
不変な状態を保持するストアでは、データが変わったときだけ現在の状態オブジェクトの参照が変わるため、getSnapshotを簡単に実装できます。その参照を返せば、安定した比較をそのまま利用できます。
これが、不変な更新パターンとこのフックの相性が非常に良い理由です。同じデータなら同じ参照になるため、Reactは不要な再レンダーをスキップできます。
無限ループを引き起こす間違い
よくある間違いは、getSnapshotを呼び出すたびにまったく新しいオブジェクトや配列を返すことです。たとえば、内部でmapやfilterを実行する場合が該当します。Reactは呼び出すたびに新しい参照を検出し、値が変わったと判断します。
その結果、再レンダーが無限に続いたり、警告が表示されたりします。これを修正するには、導出した値をキャッシュし、元のデータが実際に変わるまで同じ参照を返します。
スナップショットを安定させる
ループを防ぐには、導出データをgetSnapshotの外で計算するか、メモ化して関数がキャッシュ済みの参照を返すようにします。多くのライブラリが採用しているセレクター形式のパターンは、まさにこの安定性を管理するために存在します。
基本ルールは、ストアのデータが変わっていない限り、getSnapshotを2回呼び出した結果が完全に同じ参照になることです。
パラメーターを組み合わせる
実際には、リスナーを追加・削除するsubscribe、安定した現在の値を読み取るgetSnapshot、そしてSSRではサーバーで安全に使える値を返すgetServerSnapshotを記述します。
この3つが正しく実装されていれば、最小限の記述で、外部ストアから一貫性のある並行レンダリング対応の読み取りを行えます。
クイックチェック:useSyncExternalStoreのパラメーター
getSnapshotの役割を確認してください。
復習:useSyncExternalStore API
このフックはsubscribe、getSnapshot、そして省略可能なgetServerSnapshotを受け取ります。subscribeはリスナーを接続してunsubscribe関数を返し、getSnapshotは現在の値を同期的に読み取って参照的に安定した値を返す必要があります。getServerSnapshotはSSRで安全に使える値を提供します。
典型的な落とし穴は、呼び出すたびに新しいオブジェクトを返して無限ループを引き起こすことです。導出した値をキャッシュし、データが変わっていなければ同じ参照を返してください。
よくある質問
「useSyncExternalStore APIとパラメータ」レッスンは無料ですか?
はい。「useSyncExternalStore APIとパラメータ」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、React Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 React Academyコースには全4レッスンが含まれています。
「useSyncExternalStore APIとパラメータ」で何を学びますか?
subscribe、getSnapshot、getServerSnapshotの各引数と、それらが保証すべき条件を学びます。 ブラウザで直接実行するハンズオンコードでReact Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
React Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのReact Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「useSyncExternalStore APIとパラメータ」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このReact Academyレッスンでコードを書いて実行できますか?
はい。すべてのReact Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- 外部ストア購読の問題
- useSyncExternalStore APIとパラメータ
- ブラウザAPIの購読
- useSyncExternalStoreによるカスタムストアの構築