État Zustand avec Claude Code
Découvrez état Zustand avec Claude Code. Conseils pratiques et exemples de code inclus.
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 gratuit : aide-mémoire Claude Code en 5 minutes
Laissez simplement votre e-mail et nous vous enverrons immédiatement l'aide-mémoire A4 en PDF.
Nous traitons vos données avec soin et n'envoyons jamais de spam.
À propos de l'auteur
Masa
Ingénieur passionné par Claude Code. Il gère claudecode-lab.com, un média tech en 10 langues avec plus de 2 000 pages.
Articles similaires
7 vérifications avant de publier chaque jour un article multilingue sur Claude Code
Une checklist pratique pour publier des articles multilingues sur Claude Code chaque jour sans oublier une langue, casser les CTA ou laisser l’ancien contenu en production.
Codex Automations : confier l'analyse, les articles et le deploiement a l'IA
Guide pratique pour utiliser Codex Automations dans une operation de contenu orientee monetisation.
Claude Code × GCP Cloud Functions Guide Complet | Développement Serverless Ultra-Rapide
Optimisez GCP Cloud Functions avec Claude Code. Implémentez des triggers HTTP/Pub/Sub/Firestore, des tests locaux et l'automatisation des déploiements avec des exemples de code réels de l'expérience de Masa.