はじめに
こんにちは。アメリカ在住で独学エンジニアを目指している Taira です。
React でアプリを作成するとき、リロードしても状態を保持したいことはありませんか?
例えば、
- ログイン状態
- ダークモード設定
- カートの中身
など、毎回 API を叩かなくても良い状態は ブラウザの LocalStorage に保存すると便利です。
Zustand には、この処理を **自動化する仕組み(persist ミドルウェア)**が用意されています。今回はその使い方を解説します。
前提環境
- React + Vite または CRA
- TypeScript 使用
- Zustand インストール済み
npm install zustand
persist ミドルウェアとは?
zustand/middleware
に含まれる persist は、以下を自動で行います。
- Zustand の状態を LocalStorage に保存
- ページリロード時に LocalStorage から復元
- 保存するキー名や内容をカスタマイズ可能
基本実装例
1. カウンターの状態を保存する例
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
type CounterState = {
count: number;
increment: () => void;
reset: () => void;
};
export const useCounterStore = create<CounterState>()(
persist(
(set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
reset: () => set({ count: 0 }),
}),
{
name: 'counter-storage', // LocalStorage に保存するキー名
}
)
);
2. コンポーネントで利用する
import { useCounterStore } from './stores/counterStore';
export const Counter = () => {
const { count, increment, reset } = useCounterStore();
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>+1</button>
<button onClick={reset}>Reset</button>
</div>
);
};
ポイント:
-
useCounterStore
を呼び出すだけで LocalStorage への保存・復元が自動で行われます - 保存されたデータは
Application > Local Storage
で確認可能
保存するデータを一部だけに絞る
partialize
オプションを使うと、状態の一部だけを保存できます。
persist(
(set) => ({
count: 0,
tempValue: 'not persisted',
increment: () => set((state) => ({ count: state.count + 1 })),
}),
{
name: 'counter-storage',
partialize: (state) => ({ count: state.count }), // count だけ保存
}
);
保存先を LocalStorage → sessionStorage に変更
storage
オプションで保存先を切り替えられます。
persist(
(set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
}),
{
name: 'counter-storage',
storage: () => sessionStorage, // sessionStorage に保存
}
);
セキュリティ注意点
LocalStorage は便利ですが、XSS 攻撃に弱いため、アクセストークンや重要情報の保存には注意が必要です。
- 保存する情報は必要最小限にする
- CSP(Content Security Policy)でスクリプトの挿入を防ぐ
- 可能であれば HttpOnly Cookie を利用する
詳細は前回の記事の「SPA の XSS と CSRF 対策」でまとめています
まとめ
-
persist
ミドルウェアを使うと、状態を LocalStorage に自動保存&復元 -
name
でキー名指定、partialize
で保存対象を絞れる - 保存先を sessionStorage に切り替えることも可能
- セキュリティ対策(XSS 対策)を必ず考慮する