LocalStorage は stateful ではないので、やみくもに実装していると更新タイミング等の管理が難しい
LocalStorage を state のように扱えるカスタムフックを作成することで、ある程度使いやすくなる
カスタムフックのコード
useLocalStorage.ts
というファイルをpages
ディレクトリの外に作成する
import { useEffect, useState } from "react";
export default function useLocalStorage(key: string) {
const [value, setValue] = useState<string>("initial value");
useEffect(() => {
const res = window.localStorage.getItem(key);
if (!res) {
setValue("local storage is empty");
}
setValue(res);
}, []);
const setValueAndStorage = (newValue: string) => {
window.localStorage.setItem(key, newValue);
setValue(newValue);
};
return { value, setValueAndStorage };
}
Next.js の SSR 時にはwindow
にアクセスできないため、クライアントで実行されるuseEffect
内で LocalStorage にアクセスしている。
setValueAndStorage
関数内では、LocalStorage を更新すると同時に state の更新をしている。
カスタムフックの使用例
先に作成したuseLocalStorage
カスタムフックを使用する例
import useLocalStorage from "@/useLocalStorage";
export default function Home() {
const { value, setValueAndStorage } = useLocalStorage("storage-key");
return (
<>
<p>value: {value}</p>
<button
onClick={() => {
setValueAndStorage(Math.random().toString());
}}
>
setStorage
</button>
</>
);
}
ボタンを押すとランダムな数値を作成して、LocalStorage の保存と再レンダリングを一緒に行う。