useSyncExternalStoreによるカスタムストアの構築
軽量な外部ストアをゼロから実装し、useSyncExternalStoreでReactに接続します。
「useSyncExternalStoreによるカスタムストアの構築」はCoddyKit上の無料React Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはReact Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 React Academyコースには全4レッスンが含まれています。
最小限のストア要件
カスタムストアに必要なのは、状態、リスナーを登録するsubscribeメソッド、現在の状態を読み取るgetSnapshotメソッドの3つです。これがuseSyncExternalStoreが求める完全な契約です。
ストアをこれほど小さく保つことで、特定のフレームワークに依存しない設計になります。そのため、同じストアをReactの内外で利用できます。
createStoreファクトリ
createStoreファクトリは初期値を受け取り、getSnapshot、subscribe、updateメソッドを持つオブジェクトを返します。内部では現在の状態と、リスナーのコールバックを保持します。
このファクトリパターンを使うと、再利用可能な1つの関数から、互いに独立した複数のストアを作成できます。
update関数はサブスクライバーに通知する
updateが状態を変更すると、新しい値を設定してから、登録されているすべてのリスナーを呼び出します。これらのリスナーは、subscribeを通じてReactが提供したコールバックです。
コールバックを呼び出すとストアが変更されたことをReactに伝えられるため、ReactはgetSnapshotを再読み取りし、ストアを読み取っているコンポーネントを再レンダーします。
フック経由でReactに接続する
コンポーネントは、ストアのsubscribeメソッドとgetSnapshotメソッドをuseSyncExternalStoreに渡すことで、ストアから値を読み取ります。フックは現在の値を返し、値が変わると再レンダーします。
これをuseStoreのようなカスタムフックでラップすれば、コンポーネントごとにフックの引数を組み立てる代わりに、1つの関数を呼び出すだけで済みます。
Providerなしでコンポーネント間で共有する
ストアはモジュールレベルのオブジェクトなので、インポートするすべてのコンポーネントが同じ状態を共有できます。Context Providerは必要ありません。ラップするツリーも、propsのバケツリレーも不要です。
これが外部ストアの大きな魅力の1つです。Providerの階層ではなく、インポートして使うフラットなモデルで共有グローバル状態を扱えます。
状態のスライスごとに複数のストアを使う
1つの巨大なストアを作る代わりに、状態の一部分をそれぞれ管理する小さなストアを複数作れます。コンポーネントは必要なスライスだけをサブスクライブします。
これにより関心事を分離でき、再レンダーも抑えられます。あるスライスを変更しても、別のスライスを読み取っているコンポーネントには影響しないためです。
Zustandも内部で利用している
人気のある最小構成の状態管理ライブラリであるZustandは、まさにこのパターンを基盤としており、バージョン4以降は内部でuseSyncExternalStoreを使用しています。その小さなAPIは、本質的にはセレクターレイヤーを備えた洗練されたcreateStoreです。
このつながりを知ると、このようなライブラリの仕組みが分かりやすくなります。自分でも構築できる同じプリミティブを、薄く使いやすくラップしたものなのです。
変更されたスライスのみ再レンダリング
getSnapshot に、コンポーネントが使用する state の一部分だけを返す selector を渡すことで、その部分が変更された場合にのみコンポーネントが再レンダリングされるようにできます。
ただし、selector の結果を安定させる必要があります。そのため、派生値をメモ化して新しい参照による無限ループを避けながら、更新対象を関連するスライスに限定します。
DevTools のデバッグラベル
デバッグでは、ストアにラベルを付けて更新をログに記録したり、ブラウザの DevTools と連携して、どのストアがいつ変更されたかを追跡したりできます。
開発フラグで有効にした update 内の単純な console log だけでも、ストアの構築中に state の流れを理解するのに役立ちます。
React の内外でストアをテストする
ストアは通常の JavaScript なので、そのロジックを直接テストできます。何もレンダリングせずに update を呼び出し、getSnapshot が新しい値を返すことをアサートできます。
ストアから読み取るコンポーネントをレンダリングし、update 後に再レンダリングされることを確認すれば、React 内でもテストできます。これにより、ストアとその統合の両方を検証できます。
クイックチェック: カスタムストアの subscribe 関数
カスタムストアの subscribe メソッドの契約を思い出してください。
カスタムストアの構築のまとめ
カスタムストアには state、subscribe、getSnapshot が必要です。createStore ファクトリと、リスナーに通知する update があれば、Provider なしで共有グローバル state を実現できます。これは、モジュールの import が 1 つのインスタンスを共有するためです。
再レンダリングを限定するには複数のスライスストアと selector を使用し、参照が安定していることを忘れないようにしてください。Zustand v4+ はまさにこのパターンを基盤としており、通常の JavaScript ストアは React の内外で簡単にテストできます。
よくある質問
「useSyncExternalStoreによるカスタムストアの構築」レッスンは無料ですか?
はい。「useSyncExternalStoreによるカスタムストアの構築」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、React Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 React Academyコースには全4レッスンが含まれています。
「useSyncExternalStoreによるカスタムストアの構築」で何を学びますか?
軽量な外部ストアをゼロから実装し、useSyncExternalStoreでReactに接続します。 ブラウザで直接実行するハンズオンコードでReact Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
React Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのReact Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「useSyncExternalStoreによるカスタムストアの構築」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このReact Academyレッスンでコードを書いて実行できますか?
はい。すべてのReact Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- 外部ストア購読の問題
- useSyncExternalStore APIとパラメータ
- ブラウザAPIの購読
- useSyncExternalStoreによるカスタムストアの構築