Prompt

UseSyncExternalStoreって、結構最近の機能だったけ?

やっほー!その通り、Reactの歴史の中では**「かなり最近の、しかも玄人向けの渋い機能」**だよ!

具体的には React 18(2022年リリース) で新しく追加されたフックだね。君が情報工学で学んでいるような「並行計算」や「一貫性」というキーワードに深く関わっている、とっても知的な機能なんだ。

なぜこれが生まれたのか、そしてなぜ useEffect よりも優れている場面があるのか、サクッと整理してみよう!


1. なぜ生まれたの?(Tearingという怪奇現象)

React 18から、複数の処理を同時に並行して進める Concurrent Rendering(並行レンダリング) という機能が導入されたんだ。

これによって「表示の途中で別の処理に割り込む」ことが可能になったんだけど、ここで問題が起きたんだよ。

  • 問題: レンダリングの途中で「外部の状態(Reactの外にあるデータ)」が書き換わると、画面の上部と下部で表示されるデータが食い違ってしまうことがあるんだ。これを Tearing(引き裂き) と呼ぶよ。

2. useSyncExternalStore の凄さ

このフックは、Reactの外側(ブラウザのAPIやReduxのような外部ストア)にあるデータを、**「Reactの並行レンダリングと安全に同期させる」**ために作られたんだ。

  • useEffectとの違い:

    • useEffect + useState: 一度レンダリングしてから副作用で同期するため、一瞬古いデータが見える可能性がある。

    • useSyncExternalStore: レンダリングのプロセスそのものに外部データの読み込みを組み込むから、常に一貫したデータが表示される。

3. どんな時に使うの?

君が「クライアント側でしか実行できない処理」を考えていた時に、これを使えばもっとオシャレに解決できるケースがあるよ!

  • ブラウザのウィンドウサイズ (window.innerWidth)

  • オンライン・オフライン状態 (navigator.onLine)

  • スクロール位置の監視

  • ブラウザの履歴 (History API) の監視

これらはReactのStateじゃないけれど、Reactの画面に反映させたいよね?そんな時にこのフックが「外部と内部の安全な橋渡し」をしてくれるんだ。


⚠️ 見落とされがちな落とし穴:自作する必要はあまりない?

実は、このフックは主に 「ライブラリの作者(ReduxやZustandなどの開発者)」 向けに用意されたものなんだ。

一般的なアプリケーション開発者が日常的に使うことは少ないけれど、「ブラウザのグローバルな状態を購読したい」 という特定のニーズには、これほど頼もしい味方はいないよ。君がもし、低レイヤーに近い高度なUIコンポーネントを作りたいなら、絶対に知っておくべき武器だね!


💡 豆知識:shim(シム)

React 18より前のバージョン(React 17とか)でもこの機能を使えるように、公式から use-sync-external-store/shim というパッケージが出ているんだ。古い環境でも新しい設計思想を取り入れられる、エンジニアの優しさを感じる仕組みだよね。