Gestion de estado con Zustand y Claude Code
Aprenda sobre gestion de estado con Zustand usando Claude Code. Incluye consejos practicos y ejemplos de codigo.
Zustandでシンプルかつ強力な状態管理を実現する
Zustandは最小限のAPIで強力な状態管理を提供するReact向けライブラリです。Reduxのような複雑なボイラープレートが不要で、TypeScriptとの相性も抜群です。Claude Codeはストア設計から最適化まで的確にサポートしてくれます。
基本的なストア設計
Claude Codeにストアの設計を依頼しましょう。
> Zustandでショッピングカートのストアを作成して。
> 商品追加、削除、数量変更、合計計算を含めて。TypeScript対応で。
import { create } from "zustand";
interface CartItem {
id: string;
name: string;
price: number;
quantity: number;
}
interface CartStore {
items: CartItem[];
addItem: (item: Omit<CartItem, "quantity">) => void;
removeItem: (id: string) => void;
updateQuantity: (id: string, quantity: number) => void;
clearCart: () => void;
totalItems: () => number;
totalPrice: () => number;
}
export const useCartStore = create<CartStore>((set, get) => ({
items: [],
addItem: (item) =>
set((state) => {
const existing = state.items.find((i) => i.id === item.id);
if (existing) {
return {
items: state.items.map((i) =>
i.id === item.id ? { ...i, quantity: i.quantity + 1 } : i
),
};
}
return { items: [...state.items, { ...item, quantity: 1 }] };
}),
removeItem: (id) =>
set((state) => ({
items: state.items.filter((i) => i.id !== id),
})),
updateQuantity: (id, quantity) =>
set((state) => ({
items: state.items.map((i) =>
i.id === id ? { ...i, quantity: Math.max(0, quantity) } : i
).filter((i) => i.quantity > 0),
})),
clearCart: () => set({ items: [] }),
totalItems: () => get().items.reduce((sum, i) => sum + i.quantity, 0),
totalPrice: () =>
get().items.reduce((sum, i) => sum + i.price * i.quantity, 0),
}));
ミドルウェアの活用
Zustandのミドルウェアで永続化やログ出力を追加できます。
import { create } from "zustand";
import { persist, devtools, subscribeWithSelector } from "zustand/middleware";
import { immer } from "zustand/middleware/immer";
interface AppStore {
theme: "light" | "dark";
locale: string;
notifications: Notification[];
setTheme: (theme: "light" | "dark") => void;
setLocale: (locale: string) => void;
addNotification: (notification: Notification) => void;
removeNotification: (id: string) => void;
}
export const useAppStore = create<AppStore>()(
devtools(
persist(
immer(
subscribeWithSelector((set) => ({
theme: "light",
locale: "ja",
notifications: [],
setTheme: (theme) =>
set((state) => {
state.theme = theme;
}),
setLocale: (locale) =>
set((state) => {
state.locale = locale;
}),
addNotification: (notification) =>
set((state) => {
state.notifications.push(notification);
}),
removeNotification: (id) =>
set((state) => {
state.notifications = state.notifications.filter(
(n) => n.id !== id
);
}),
}))
),
{
name: "app-store",
partialize: (state) => ({
theme: state.theme,
locale: state.locale,
}),
}
),
{ name: "AppStore" }
)
);
スライスパターンで大規模ストアを分割
大規模アプリケーションでは、ストアをスライスに分割して管理します。
// userSlice.ts
interface UserSlice {
user: User | null;
isAuthenticated: boolean;
login: (credentials: LoginCredentials) => Promise<void>;
logout: () => void;
}
const createUserSlice: StateCreator<StoreState, [], [], UserSlice> = (set) => ({
user: null,
isAuthenticated: false,
login: async (credentials) => {
const user = await authApi.login(credentials);
set({ user, isAuthenticated: true });
},
logout: () => set({ user: null, isAuthenticated: false }),
});
// uiSlice.ts
interface UISlice {
sidebarOpen: boolean;
modalStack: string[];
toggleSidebar: () => void;
openModal: (id: string) => void;
closeModal: () => void;
}
const createUISlice: StateCreator<StoreState, [], [], UISlice> = (set) => ({
sidebarOpen: true,
modalStack: [],
toggleSidebar: () => set((s) => ({ sidebarOpen: !s.sidebarOpen })),
openModal: (id) => set((s) => ({ modalStack: [...s.modalStack, id] })),
closeModal: () => set((s) => ({ modalStack: s.modalStack.slice(0, -1) })),
});
// store.ts - スライスを統合
type StoreState = UserSlice & UISlice;
export const useStore = create<StoreState>()((...a) => ({
...createUserSlice(...a),
...createUISlice(...a),
}));
セレクターによるパフォーマンス最適化
不要な再レンダリングを防ぐために、セレクターを使い分けます。
// 個別の値を取得(推奨)
function CartIcon() {
const totalItems = useCartStore((state) => state.totalItems());
return <span>カート ({totalItems})</span>;
}
// shallow比較でオブジェクトを取得
import { useShallow } from "zustand/react/shallow";
function CartSummary() {
const { totalItems, totalPrice } = useCartStore(
useShallow((state) => ({
totalItems: state.totalItems(),
totalPrice: state.totalPrice(),
}))
);
return (
<div>
<p>{totalItems}点の商品</p>
<p>合計: ¥{totalPrice.toLocaleString()}</p>
</div>
);
}
Summary
Zustandはそのシンプルさと柔軟性で、多くのReactプロジェクトの状態管理に適しています。Claude Codeを使えば、ストア設計からミドルウェア構成、パフォーマンス最適化まで一貫して素早く実装できます。
アトミックな状態管理のアプローチはJotaiアトミック状態管理を、データ取得との連携はTanStack Query活用ガイドを参照してください。Zustand公式ドキュメントも確認しておきましょう。
PDF gratuito: Hoja de trucos de Claude Code en 5 minutos
Solo deja tu correo y te enviaremos al instante la hoja de trucos en una página A4.
Cuidamos tus datos personales y nunca enviamos spam.
Sobre el autor
Masa
Ingeniero apasionado por Claude Code. Dirige claudecode-lab.com, un medio tecnológico en 10 idiomas con más de 2.000 páginas.
Artículos relacionados
7 comprobaciones antes de publicar cada día un artículo multilingüe sobre Claude Code
Una lista práctica para publicar artículos multilingües sobre Claude Code todos los días sin olvidar idiomas, romper CTAs ni dejar páginas antiguas en producción.
Que es Codex Automations y como dejar que la IA gestione contenido mientras duermes
Guia practica para usar Codex Automations en analitica, articulos, CTA, despliegue y monetizacion.
Claude Code × GCP Cloud Functions Guía Completa | Desarrollo Serverless Ultrarrápido
Optimiza GCP Cloud Functions con Claude Code. Implementa triggers HTTP/Pub/Sub/Firestore, pruebas locales y automatización de despliegues con ejemplos de código reales de la experiencia de Masa.