はじめに
Reactで開発していると、「ユーザーの設定をローカルに保存したい」「ダークモードを記憶させたい」といった要件が高い頻度で登場します。
そんなときに便利なのが、localStorage
を React の useState
のように扱えるカスタムフック useLocalStorage
です。
今回は上記機能の実装方法や実際の利用方法などを備忘録的にまとめていきたいと思います。
useLocalStorage とは?
通常、localStorage
は window.localStorage.getItem()
/ setItem()
を使って操作しますが、
- 値の変更で再レンダリングされない
- 型が文字列限定なので変換が面倒
- 毎回try-catch書くのがつらい
などの課題があるかと思います。
それを解決するのが、カスタムフック useLocalStorage
です。
useLocalStorage
の実装方法
以下が useLocalStorage
の実装とその使用例です。
import { useState, useEffect } from "react";
function useLocalStorage<T>(key: string, initialValue: T) {
const [storedValue, setStoredValue] = useState<T>(() => {
try {
if (typeof window === "undefined") return initialValue;
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
console.warn(`Error reading localStorage key "${key}":`, error);
return initialValue;
}
});
useEffect(() => {
try {
window.localStorage.setItem(key, JSON.stringify(storedValue));
} catch (error) {
console.warn(`Error setting localStorage key "${key}":`, error);
}
}, [key, storedValue]);
return [storedValue, setStoredValue] as const;
}
export default useLocalStorage;
この実装の特徴としては、
-
initialValue
がそのままデフォルト値になる -
T
型パラメータで、任意の型を保持可能 - データを JSON 化して保存 / 復元
以上になります。
次にuseLocalStorageの使用例になります。
import useLocalStorage from "@/hooks/useLocalStorage";
const ThemeSwitcher = () => {
const [theme, setTheme] = useLocalStorage<"light" | "dark">("theme", "light");
const toggleTheme = () => {
setTheme(theme === "light" ? "dark" : "light");
};
return (
<div>
<p>現在のテーマ: {theme}</p>
<button onClick={toggleTheme}>
トグルテーマ
</button>
</div>
);
};
export default ThemeSwitcher;
使用例は以上です。
上記のように保存しておくことで、ページをリロードしても前回選んだテーマが復元されます。
使用時の注意点
-
localStorage
は ブラウザにしか存在しない為、SSR時(Next.js)にはtypeof window !== "undefined"
チェックが必要になります。 - 保存可能なデータは基本的に JSONでシリアライズ可能なもの(関数や
Date
インスタンスなどはNG) - データサイズに上限あり(約5MB)
まとめ
useLocalStorage
は、一度作れば全プロジェクトで再利用可能な便利ユーティリティです。
ちょっとしたカスタマイズで sessionStorage
対応にも拡張できますし、Cookieベースのバリエーションもアリかと思います。
さいごに
健康管理のモチベーションもしっかり維持して邁進していきます!