📝

【React】useSyncExternalStoreを使用してlocalStorageから値を読み込んだ話

2024/03/06に公開

はじめに

こんにちは、daikiです!
普段はフロントエンドエンジニアとして業務をしており、
主にTypeScriptやNext.jsなどの技術を触っています。
開発の状況によってはバックエンドも行っており、使用言語はGoです。

今回はReact HookであるuseSyncExternalStoreを使用してローカルストレージから値を取得した話をしていきたいと思います!

useSyncExternalStore

useSyncExternalStoreは外部のデータストアから値を読み込みたい時に使用できるReact Hookです。
公式にも記載されていますが、その他にもブラウザAPIから値を読み込みたい時にも使用されます。
今回はローカルストレージにある値が変更された際に検知してレンダリングさせたかったため、useSyncExternalStoreを使用しました。

実装

まず、useSyncExternalStoreの第一引数に指定するsubscribeです。
ローカルストレージやセッションストレージのデータが変更された際にcallback関数が呼び出されるように設定し、イベントリスナーを後で削除するための関数を返しています。
subscribe関数はstorageイベントの購読を開始し、その購読を終了する関数を返す役割。

const subscribe = (callback: () => void) => {
  window.addEventListener("storage", callback);
  return () => {
    window.removeEventListener("storage", callback);
  };
};

これをコンポーネント毎に直接書き込むのではなく、カスタムフック化します(どのコンポーネントからでも使えるように)。

const setTest = (test: string) => {
  window.localStorage.setItem("test", test);
  window.dispatchEvent(new Event("storage"));
};

export const useTest = () => {
  const test =
    useSyncExternalStore(
      subscribe,
      () => localStorage.getItem("test"), // 現在の値を返す関数
      () => null, // サーバーコンポーネントでサーバーのスナップショットを取得するための関数。今回はクライアント専用のためnullを指定。
    ) || "";

  return { test, setTest };
};

このように実装した結果どのコンポーネントからもローカルストレージの値を読み込むことができ、変更を検知してレンダリングするようになりました。

最後に

今回はuseSyncExternalStoreを使用してローカルストレージの値を読み込み、変更を検知する実際に使用した実装をまとめました。この実装で初めてuseSyncExternalStoreを使用したので、また同じような要件があれば使用していきたいと思います!

Discussion