Reactのカスタムフックでローカルストレージを管理する方法を初心者向けにやさしく解説!
生徒
「Reactでデータを保存しておきたいんですが、画面を閉じても残るようにすることってできますか?」
先生
「できますよ。ローカルストレージという仕組みを使えば、ブラウザにデータを保存できます。しかもカスタムフックを作れば、どの画面からでも簡単に使えるようになります。」
生徒
「カスタムフックって難しい機能なんですか? React初心者のぼくでも作れるでしょうか?」
先生
「大丈夫です。ローカルストレージとReactの仕組みを分かりやすく説明しながら、実際にコードも紹介しますね。」
1. ローカルストレージとは?初心者向けにわかりやすく説明
ローカルストレージとは、ブラウザが持っている「小さな保管箱」のようなものです。ユーザーがページを閉じてもデータが消えず、そのまま保存され続けます。例えば、テーマ(ダークモード/ライトモード)、ユーザー名、フォームの下書きなどを保存しておくのに便利です。
ただしローカルストレージは文字列しか保存できません。そのため、オブジェクトや配列を保存するときは、いったんJSON.stringify()で文字列に変換し、読み出すときはJSON.parse()で元に戻します。
この変換やエラーチェックを毎回書くのは大変なので、Reactではカスタムフックにまとめる方法がよく使われます。
2. カスタムフックとは?React初心者にもわかる説明
カスタムフックとは、Reactに標準であるuseStateやuseEffectなどを組み合わせて、自分用の便利なフックを作る仕組みです。名前の先頭に「use」を付ける決まりがあります。
例えば、ローカルストレージにデータを保存して、画面が変わっても読み出せる便利な関数を作るなら、useLocalStorageという名前になります。
カスタムフックを使うメリットには以下があります:
- 複数のコンポーネントで同じ仕組みを使える
- 難しい処理を中に隠して、外からは簡単に使える
- ローカルストレージのエラー処理も一括管理できて安全
3. 実際にカスタムフック(useLocalStorage)を作ってみよう
ここからはReactのプログラムコードを使って、ローカルストレージを管理するカスタムフックを作っていきます。初期値の読み込みやエラー処理、JSON変換も自動で行う安全な仕組みです。
import { useState, useEffect } from "react";
function useLocalStorage(key, initialValue) {
const [value, setValue] = useState(() => {
try {
const stored = localStorage.getItem(key);
return stored ? JSON.parse(stored) : initialValue;
} catch {
return initialValue;
}
});
useEffect(() => {
try {
localStorage.setItem(key, JSON.stringify(value));
} catch (error) {
console.error("保存時にエラーが発生しました", error);
}
}, [key, value]);
return [value, setValue];
}
export default useLocalStorage;
4. 作ったカスタムフックを使って値を保存してみよう
次に、先ほど作ったuseLocalStorageを実際のコンポーネントで使ってみましょう。テーマ(ライト/ダーク)を保存する例です。
import React from "react";
import useLocalStorage from "./useLocalStorage";
function App() {
const [theme, setTheme] = useLocalStorage("theme", "light");
const toggleTheme = () => {
setTheme(theme === "light" ? "dark" : "light");
};
return (
<div className={theme}>
<h1>テーマ切替デモ</h1>
<button onClick={toggleTheme}>テーマを切り替える</button>
</div>
);
}
export default App;
5. ローカルストレージを安全に扱うための注意点
ローカルストレージは便利ですが、扱い方を間違えるとエラーの原因になったり、データが壊れたりします。初心者向けに大切なポイントをまとめました。
- JSONが壊れていると読み取りエラーになる:必ずtry/catchで保護すること。
- データは文字列だけ保存できる:オブジェクトは必ずJSON変換する。
- 容量に上限がある:大量のデータを保存しないこと。
- 機密情報は保存しない:パスワードやトークンの保存はNG。
カスタムフックにまとめることで、これらの問題の多くを自動で解決できるため、初心者にもおすすめのアプローチです。
6. カスタムフックの応用例
ローカルストレージは、実務でもよく使われる場面が多くあります。例えば:
- テーマ設定(ダーク/ライト)の保存
- フォームの下書き保存
- アプリの表示モードやフィルタ条件の保存
- 簡単なキャッシュ(前回の値を残す)
これらはすべて、カスタムフック一つで効率よく扱えるため、Reactでの開発がよりシンプルになります。
まとめ
Reactでローカルストレージを管理する方法を振り返ると、まずローカルストレージが「ブラウザに長期間データを保存できる仕組み」であり、アプリを閉じても情報が残る便利な機能であることが理解できました。とくにテーマ設定やフォームの下書き、簡単なユーザー設定など、アプリの快適さを高める重要な役割を果たします。また、文字列しか保存できない特性をきちんと理解し、オブジェクトを保存する際にはJSON形式に変換する必要がある点も重要でした。 さらに、Reactのカスタムフックを使うことで、ローカルストレージの読み書きを安全に一箇所へまとめられることも大きなメリットでした。useStateとuseEffectを組み合わせることで、初期値の自動読み込み・変更時の保存処理・エラー保護などを一連の仕組みとして提供し、どのコンポーネントからでも呼び出すだけで活用できます。このようにパターン化されたロジックは、再利用性や保守性を向上させ、初心者から実務レベルまで役立つ考え方になります。 また、ローカルストレージを使う際の注意点として「容量の上限」「機密データを保存しない」「JSONエラーへの対策」など、安全性を意識しながら設計する姿勢も学びました。ローカルストレージは便利ですが、必要以上に依存せず、データの性質に応じて使い分ける判断力も求められます。最後に、Reactアプリ内で利用例としてテーマ切り替えの保存を扱いましたが、この仕組みは他にも「ログイン中の表示設定」「ユーザーの入力内容保持」「アプリ表示モード記憶」など応用範囲が広く、実際の開発で活躍する機能です。
サンプルプログラム(振り返り用)
ローカルストレージを管理するカスタムフックの基本構造を再掲します。
import { useState, useEffect } from "react";
function useLocalStorage(key, initialValue) {
const [value, setValue] = useState(() => {
try {
const stored = localStorage.getItem(key);
return stored ? JSON.parse(stored) : initialValue;
} catch {
return initialValue;
}
});
useEffect(() => {
try {
localStorage.setItem(key, JSON.stringify(value));
} catch (error) {
console.error("保存時にエラーが発生しました", error);
}
}, [key, value]);
return [value, setValue];
}
export default useLocalStorage;
このコードでは、初期化の段階でローカルストレージから安全に値を読み取り、変更があれば同期するよう設計されています。Reactのカスタムフックとして完成度の高い形であり、他の用途にも転用できる応用性を持っています。学習を通して、より実践的なReactアプリの構築に必要な基礎力が身についたことでしょう。
生徒
「ローカルストレージって便利なんですね!Reactと組み合わせると、自動で保存されたり読み込まれたりしてすごく便利でした。」
先生
「そうですね。カスタムフックにまとめることで、複雑な処理もわかりやすく整理されます。アプリの規模が大きくなるほど効果を実感できますよ。」
生徒
「JSONに変換する理由もよくわかりました。文字列しか保存できないからなんですね。」
先生
「そのとおりです。仕組みを理解して使うとエラーも減り、安全にデータを扱えるようになります。今回のフックは他にも応用できますのでぜひ活用してください。」
生徒
「はい!テーマ保存以外にも使えそうなので、いろいろ試してみます!」