zustand

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Zustand State Management Guide

Zustand状态管理指南

This skill provides guidelines, patterns, and best practices for working with Zustand in this project.
本指南提供了在本项目中使用Zustand的规范、模式和最佳实践。

Quick Start

快速开始

For detailed store patterns, middleware usage, and comprehensive examples, please refer to
references/patterns.md
.
如需了解详细的store模式、middleware用法和完整示例,请参考
references/patterns.md

Core Philosophy

核心理念

  • Shared Client State Only: Use Zustand for shared client state, not server state (use TanStack Query for that).
  • Domain-Specific Stores: Keep stores focused on specific domains.
  • Type Safety: Leverage TypeScript for fully typed stores.
  • Simplicity: Prefer simplicity over complex abstractions.
  • 仅用于共享客户端状态:Zustand用于管理共享客户端状态,不要用于服务端状态(服务端状态请使用TanStack Query)。
  • 面向特定业务域的Store:保持store聚焦于特定业务域。
  • 类型安全:利用TypeScript实现store的全类型覆盖。
  • 简洁优先:优先选择简洁方案,避免过度复杂的抽象。

Store Organization

Store组织规范

Essential Patterns

核心模式

  • Create separate stores for different domains
  • Use slices pattern for large stores
  • Keep stores close to features that use them
  • Export typed selector hooks for better DX and performance
  • 为不同业务域创建独立的store
  • 大型store使用slices模式拆分
  • 将store存放在靠近使用它的功能模块附近
  • 导出带类型的selector钩子,提升开发体验和性能

Recommended Middleware Stack

推荐中间件组合

Use the following middleware combination for production stores:
typescript
import { create } from "zustand";
import { devtools, persist } from "zustand/middleware";
import { immer } from "zustand/middleware/immer";

export const useExampleStore = create<ExampleState>()(
  devtools(
    persist(
      immer((set, get) => ({
        // state and actions
      })),
      { name: "example-storage" }
    ),
    { name: "example-store" }
  )
);
生产环境的store推荐使用以下中间件组合:
typescript
import { create } from "zustand";
import { devtools, persist } from "zustand/middleware";
import { immer } from "zustand/middleware/immer";

export const useExampleStore = create<ExampleState>()(
  devtools(
    persist(
      immer((set, get) => ({
        // state and actions
      })),
      { name: "example-storage" }
    ),
    { name: "example-store" }
  )
);

Store Structure Template

Store结构模板

typescript
interface StoreState {
  // State properties
  data: DataType | null;
  isLoading: boolean;
  // Group actions together
  actions: {
    fetchData: () => Promise<void>;
    updateData: (updates: Partial<DataType>) => void;
    reset: () => void;
  };
}
typescript
interface StoreState {
  // State properties
  data: DataType | null;
  isLoading: boolean;
  // Group actions together
  actions: {
    fetchData: () => Promise<void>;
    updateData: (updates: Partial<DataType>) => void;
    reset: () => void;
  };
}

Selector Hooks Pattern

选择器钩子模式

Always create selector hooks for performance optimization:
typescript
// Bad - subscribes to entire store
const { user, isLoading } = useAuthStore();

// Good - subscribes only to specific slices
export const useUser = () => useAuthStore((state) => state.user);
export const useIsLoading = () => useAuthStore((state) => state.isLoading);
export const useAuthActions = () => useAuthStore((state) => state.actions);
始终创建selector钩子进行性能优化:
typescript
// Bad - subscribes to entire store
const { user, isLoading } = useAuthStore();

// Good - subscribes only to specific slices
export const useUser = () => useAuthStore((state) => state.user);
export const useIsLoading = () => useAuthStore((state) => state.isLoading);
export const useAuthActions = () => useAuthStore((state) => state.actions);

Best Practices

最佳实践

  1. Keep stores focused on specific domains
  2. Use TypeScript for full type safety
  3. Leverage middleware for common patterns (devtools, persist, immer)
  4. Create selector hooks for performance
  5. Use immer for complex nested state updates
  6. Persist only necessary state - use
    partialize
    option
  7. Test stores thoroughly
  8. Handle async operations properly with loading/error states
  9. Implement optimistic updates when appropriate
  10. Document store structure and actions
  1. 保持store聚焦于特定业务域
  2. 使用TypeScript实现全类型安全
  3. 利用middleware实现通用模式(devtools、persist、immer)
  4. 创建selector钩子提升性能
  5. 复杂嵌套状态更新使用immer
  6. 仅持久化必要状态 - 使用
    partialize
    配置项
  7. 对store进行充分测试
  8. 妥善处理异步操作,配套loading/error状态
  9. 合适场景下实现乐观更新
  10. 为store结构和action添加文档

Common Tasks

常见任务

Creating a New Store

新建Store

  1. Define the state interface with typed actions
  2. Create the store with appropriate middleware
  3. Export selector hooks for each state slice
  4. Add to the feature's barrel export
  1. 定义带类型化action的state接口
  2. 使用合适的中间件创建store
  3. 为每个state分片导出selector钩子
  4. 添加到对应功能模块的barrel导出文件中

Persisting State

状态持久化

Use the
persist
middleware with
partialize
to persist only necessary data:
typescript
persist(
  (set) => ({ /* ... */ }),
  {
    name: "store-key",
    partialize: (state) => ({
      // Only persist these fields
      user: state.user,
      preferences: state.preferences,
    }),
  }
);
使用
persist
中间件搭配
partialize
配置,仅持久化必要数据:
typescript
persist(
  (set) => ({ /* ... */ }),
  {
    name: "store-key",
    partialize: (state) => ({
      // Only persist these fields
      user: state.user,
      preferences: state.preferences,
    }),
  }
);

Using Immer for Updates

使用Immer更新状态

Immer allows mutable-style updates that produce immutable state:
typescript
immer((set) => ({
  updateNested: (id, value) => {
    set((state) => {
      const item = state.items.find((i) => i.id === id);
      if (item) {
        item.value = value; // Mutable style, but produces immutable state
      }
    });
  },
}));
Immer允许使用可变写法实现不可变状态更新:
typescript
immer((set) => ({
  updateNested: (id, value) => {
    set((state) => {
      const item = state.items.find((i) => i.id === id);
      if (item) {
        item.value = value; // Mutable style, but produces immutable state
      }
    });
  },
}));

Validation Checklist

校验清单

Before finishing a task involving Zustand:
  • Store is domain-specific and focused
  • TypeScript interfaces are properly defined
  • Middleware is applied in correct order (devtools > persist > immer)
  • Selector hooks are created for performance
  • Actions are grouped in an
    actions
    object
  • Only necessary state is persisted
  • Run type checks (
    pnpm run typecheck
    ) and tests (
    pnpm run test
    )
For detailed rules, examples, and anti-patterns, please consult
references/patterns.md
.
完成涉及Zustand的开发任务前,请检查以下项:
  • Store是面向特定业务域的,职责单一
  • TypeScript接口定义完整正确
  • 中间件按正确顺序应用(devtools > persist > immer)
  • 已创建selector钩子优化性能
  • Action统一分组在
    actions
    对象中
  • 仅持久化必要的状态
  • 运行类型检查(
    pnpm run typecheck
    )和测试(
    pnpm run test
如需了解详细规则、示例和反模式,请参考
references/patterns.md