关于 zustand
面向在项目中使用 Zustand 的开发者,提供状态管理模式与实践指南。内容涵盖领域化 Store、TypeScript 类型、选择器及中间件,并强调仅用 Zustand 管理共享客户端状态。
主要功能
- 01领域专用 Store 设计
- 02TypeScript 类型安全
- 03切片模式组织大型 Store
- 04选择器 Hook 优化订阅
- 05持久化与 Immer 中间件
适用场景
- 01规划新功能的状态 Store
- 02为大型 Store 拆分切片
- 03减少组件对无关状态的订阅
- 04选择需持久化的状态字段
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ pedronauck/ skills --skill zustand安装后在 Claude Code 中输入/zustand确认已加载。
附带文件references/patterns.md
详细介绍
Zustand 状态管理指南
本技能为在本项目中使用 Zustand 提供指南、模式和最佳实践。
快速入门
有关详细的 store 模式、中间件用法和全面示例,请参阅 references/patterns.md。
核心理念
- 仅管理共享客户端状态:使用 Zustand 管理共享客户端状态,而非服务端状态(服务端状态请使用 TanStack Query)。
- 按领域划分 store:让 store 专注于特定领域。
- 类型安全:利用 TypeScript 为 store 提供完整类型。
- 保持简单:优先选择简单方案,避免复杂抽象。
Store 组织
基本模式
- 为不同领域创建独立的 store
- 对大型 store 使用切片模式
- 将 store 放在使用它们的功能附近
- 导出带类型的选择器 Hook,以提升开发体验和性能
推荐的中间件组合
生产环境中的 store 建议使用以下中间件组合:
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 结构模板
interface StoreState {
// State properties
data: DataType | null;
isLoading: boolean;
// Group actions together
actions: {
fetchData: () => Promise<void>;
updateData: (updates: Partial<DataType>) => void;
reset: () => void;
};
}
选择器 Hook 模式
始终创建选择器 Hook,以优化性能:
// 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);
最佳实践
- 让 store 专注于特定领域
- 使用 TypeScript 确保完整的类型安全
- 利用中间件处理常见模式(devtools、persist、immer)
- 创建选择器 Hook以提升性能
- 使用 immer更新复杂的嵌套状态
- 仅持久化必要状态——使用
partialize选项 - 全面测试 store
- 妥善处理异步操作,维护加载和错误状态
- 在适当时实现乐观更新
- 记录 store 结构和操作
常见任务
创建新 Store
- 定义包含带类型操作的状态接口
- 使用合适的中间件创建 store
- 为每个状态切片导出选择器 Hook
- 将其添加到功能的 barrel 导出中
持久化状态
使用 persist 中间件和 partialize,仅持久化必要的数据:
persist(
(set) => ({ /* ... */ }),
{
name: "store-key",
partialize: (state) => ({
// Only persist these fields
user: state.user,
preferences: state.preferences,
}),
}
);
使用 Immer 更新状态
Immer 支持以可变风格编写更新逻辑,同时生成不可变状态:
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
}
});
},
}));
验证清单
完成涉及 Zustand 的任务前,请确认:
- Store 按领域划分且职责明确
- TypeScript 接口定义正确
- 中间件按正确顺序应用(devtools > persist > immer)
- 已创建选择器 Hook 以提升性能
- 操作已归入
actions对象 - 仅持久化必要状态
- 运行类型检查(
pnpm run typecheck)和测试(pnpm run test)
有关详细规则、示例和反模式,请参阅 references/patterns.md。
评论
支持 Markdown