🐻
ZustandのPersisting store dataを使ってみる
この記事は「React Advent Calendar 2025」の4日目の記事です。
Reactを触って最初に驚くのは、状態管理に対する選択肢の多さです。State、Reducer,Context...そして外部ライブラリのRedux、Zustand、Jotai...どんなときに、どれを使うのがよいのか?調べれば調べるほど迷路に迷い込んだ気分になります。
なるべく外部ライブラリを使わないほうが良いのかな?と思いつつ、Zustandを触ってみたところ、やりたいことが簡単にできそうだったので、今の案件で使ってみようと思ってます。
主に画面間でのパラメータ保持に使いたいと思っていて、ZustandのMiddlewareであるPersisting store dataを触りました。sessionStorageやlocalStorageが使いやすい印象です。
キーバリュー形式のパラメータを想定して、Mapを保持するためのuseStorageMapを定義します。
UseStorageMap.ts
import { create } from 'zustand';
import { persist, createJSONStorage } from 'zustand/middleware';
import type { PersistStorage , StorageValue } from 'zustand/middleware';
interface StorageMapParam {
param: Map<string, any>;
}M
const storage: PersistStorage<StorageMapParam> = {
getItem: (name) => {
const val = localStorage.getItem(name);
if (val === null) return null;
const existingValue = JSON.parse(val);
return {
...existingValue,
state: {
...existingValue.state,
param: new Map(existingValue.state.param),
}
}
},
setItem: (name, value: any) => {
const str = JSON.stringify({
...value,
state: {
...value.state,
param: Array.from(value.state.param.entries()),
},
})
localStorage.setItem(name, str);
},
removeItem: (name) => {
localStorage.removeItem(name)
}
}
interface StorageMapState {
param: Map<string, any>;
getItem: (key: string) => any;
setItem: (val: Map<string, any>) => void;
}
export const useStorageMap = create<StorageMapState>()(
persist(
(set, get) => ({
param: new Map(),
getItem: (key: string): any => {
return get().param.get(key);
},
setItem: (val: Map<string, any>) => set({ param: val }),
}),
{
name: 'storage-map-param', // ストレージのキー名
storage, // sessionStorageを使用
},
),
)
呼び出し元画面でボタンを押したタイミングで、次の画面に渡したいパラメータをセットします。
from.tsx
import { useNavigate } from "react-router";
import { useStorage } from "../store/useStorage";
import { useStorageMap } from "../store/useStorageMap";
export default function from() {
const navigate = useNavigate();
const storeMap = useStorageMap();
const nextPage = () => {
storeMap.setItem(new Map([["key1", "value1"], ["key2", 42]]));
navigate("/to");
}
return (
<div>
<button onClick={nextPage}>次の画面にすすむ</button>
</div>
)
}
次の画面でuseStoreMap()を使ってパラメータを取得して表示します。
to.tsx
import { useEffect } from "react";
import { useStorage } from "../store/useStorage";
import { useStorageMap } from "../store/useStorageMap";
export default function to() {
const storeMap = useStorageMap();
useEffect(() => {
console.log("Stored Map Value:", storeMap.getItem("key1"));
console.log("Stored Map Value:", storeMap.getItem("key2"));
}, []);
return (
<div>
<p>前の画面でセットされたMapの値は key1: {storeMap.getItem("key1")}, key2: {storeMap.getItem("key2")}</p>
</div>
)
}

Discussion