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 というパッケージが出ているんだ。古い環境でも新しい設計思想を取り入れられる、エンジニアの優しさを感じる仕組みだよね。