Use Cases

Zustand:Claude Code 实战指南

了解zustand:Claude Code 实战. 包含实用技巧和代码示例。

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>
  );
}

总结

Zustandは那个シンプルさと柔軟性で、多くのReact项目の状態管理に適しています。借助 Claude Code,ストア设计から中间件结构、性能优化まで一貫して快速实现可以。

アトミックな状態管理のアプローチはJotaiアトミック状態管理を、数据获取との联动はTanStack Query活用指南Zustand官方文档也建议确认一下。

#Claude Code #Zustand #React #state management #TypeScript