关于 zustand-state-management
帮助在 React 和 TypeScript 应用中构建 Zustand 状态存储的实用 Skill。内容涵盖类型化与持久化存储、选择器、中间件、常见模式和问题排查。
主要功能
- 01类型化存储配置
- 02基于选择器访问状态
- 03使用 localStorage 或 sessionStorage 持久化
- 04devtools 等中间件
- 05模式与故障排查参考
适用场景
- 01为 React 应用添加客户端状态
- 02在页面重新加载后保留用户偏好
- 03排查 TypeScript 中间件或水合问题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ secondsky/ claude-skills --skill zustand-state-management安装后在 Claude Code 中输入/zustand-state-management确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/example-template.txtreferences/advanced-topics.mdcommon-patterns.mdexample-reference.mdknown-issues.mdmiddleware-guide.mdmigration-guide.mdnextjs-hydration.mdtypescript-patterns.mdscripts/check-versions.shexample-script.shtemplates/async-actions-store.tsbasic-store.tscomputed-store.tsdevtools-store.tsnextjs-store.tspersist-store.tsslices-pattern.tstypescript-store.ts详细介绍
Zustand 状态管理
状态:已可用于生产环境 ✅ 最近更新:2026-08-03 最新版本:[email protected] 依赖项:React 18+、TypeScript 5+
快速入门(3 分钟)
1. 安装 Zustand
bun add zustand # preferred
# or: npm install zustand
# or: yarn add zustand
为什么选择 Zustand?
- API 精简:只需学习 1 个函数(
create) - 无样板代码:无需 Provider、reducer 或 action
- TypeScript 优先:类型推断出色
- 快速:细粒度订阅可避免不必要的重新渲染
- 灵活:提供用于持久化、开发者工具等的中间件
2. 创建你的第一个 Store(TypeScript)
import { create } from 'zustand'
interface BearStore {
bears: number
increase: (by: number) => void
reset: () => void
}
const useBearStore = create<BearStore>()((set) => ({
bears: 0,
increase: (by) => set((state) => ({ bears: state.bears + by })),
reset: () => set({ bears: 0 }),
}))
重要:注意 create<T>()() 中的双括号,TypeScript 配合中间件时必须这样写。
3. 在组件中使用 Store
import { useBearStore } from './store'
function BearCounter() {
const bears = useBearStore((state) => state.bears)
return <h1>{bears} around here...</h1>
}
function Controls() {
const increase = useBearStore((state) => state.increase)
return <button onClick={() => increase(1)}>Add bear</button>
}
这样做有效的原因:
- 只有当所选状态发生变化时,组件才会重新渲染
- 无需 Context Provider
- 选择器函数可提取特定的状态片段
3 种模式的设置流程
模式 1:基础 Store(JavaScript)
适用于不使用 TypeScript 的简单场景:
import { create } from 'zustand'
const useStore = create((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
decrement: () => set((state) => ({ count: state.count - 1 })),
}))
适用场景:
- 原型开发
- 小型应用
- 项目中不使用 TypeScript
模式 2:TypeScript Store(推荐)
适用于需要类型安全的生产应用:
import { create } from 'zustand'
// Define store interface
interface CounterStore {
count: number
increment: () => void
decrement: () => void
}
// Create typed store
const useCounterStore = create<CounterStore>()((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
decrement: () => set((state) => ({ count: state.count - 1 })),
}))
要点:
- 分别为状态和操作定义接口
- 使用
create<T>()()语法(通过柯里化支持中间件) - IDE 自动补全和类型检查完整
模式 3:持久化 Store
适用于需要在页面重新加载后保留的状态:
import { create } from 'zustand'
import { persist, createJSONStorage } from 'zustand/middleware'
interface UserPreferences {
theme: 'light' | 'dark' | 'system'
language: string
setTheme: (theme: UserPreferences['theme']) => void
setLanguage: (language: string) => void
}
const usePreferencesStore = create<UserPreferences>()(
persist(
(set) => ({
theme: 'system',
language: 'en',
setTheme: (theme) => set({ theme }),
setLanguage: (language) => set({ language }),
}),
{
name: 'user-preferences', // unique name in localStorage
storage: createJSONStorage(() => localStorage), // optional: defaults to localStorage
},
),
)
这很重要,因为:
- 状态会自动保存到 localStorage
- 页面重新加载后会恢复
- 也支持 sessionStorage
- 自动处理序列化
关键规则
务必做到
✅ 在 TypeScript 中使用 create<T>()()(双括号),以兼容中间件
✅ 分别为状态和操作定义接口
✅ 使用选择器函数提取特定的状态片段
✅ 对派生状态使用带更新函数的 set:set((state) => ({ count: state.count + 1 }))
✅ 为持久化中间件存储键使用唯一名称
✅ 使用 hasHydrated 标记模式处理 Next.js 水合
✅ 使用 shallow 选择多个值
✅ 保持操作纯粹(除更新状态外不产生副作用)
绝不可做
❌ 在 TypeScript 中使用 create<T>(...)(单括号)——这会破坏中间件类型
❌ 直接修改状态:set((state) => { state.count++; return state })——应使用不可变更新
❌ 在选择器中创建新对象:useStore((state) => ({ a: state.a }))——会导致无限渲染
❌ 多个 Store 使用相同的存储名称——会导致数据冲突
❌ 未检查水合状态就在 SSR 期间访问 localStorage
❌ 使用 Zustand 管理服务端状态——应改用 TanStack Query
❌ 直接导出 Store 实例——始终导出 Hook
避免已知问题(5 个问题)
| 问题 | 错误 | 快速修复 |
|---|---|---|
| #1 水合不匹配 | “文本内容不匹配” | 使用 _hasHydrated 标记 + onRehydrateStorage |
| #2 TypeScript 推断 | 中间件导致类型失效 | 使用带双括号的 create<T>()() |
| #3 导入错误 | “未导出 createJSONStorage” | 升级到 [email protected]+ |
| #4 无限循环 | 浏览器冻结 | 使用 shallow 或分开使用选择器 |
| #5 切片类型 | StateCreator 类型失败 | 显式指定 StateCreator<Combined, [], [], Slice> |
最关键——TypeScript 双括号:
// ❌ WRONG: create<T>((set) => ...)
// ✅ CORRECT: create<T>()((set) => ...)
参见:references/known-issues.md,其中提供了完整解决方案和代码示例。
中间件配置
import { create } from 'zustand'
import { devtools, persist } from 'zustand/middleware'
const useStore = create<MyStore>()(
devtools(
persist(
(set) => ({ /* store definition */ }),
{ name: 'my-storage' },
),
{ name: 'MyStore' },
),
)
| 中间件 | 用途 | 导入路径 |
|---|---|---|
persist | localStorage/sessionStorage | zustand/middleware |
devtools | 集成 Redux DevTools | zustand/middleware |
immer | 可变更新语法 | zustand/middleware/immer |
顺序很重要:devtools(persist(...)) 会在 DevTools 中显示持久化操作。
参见:references/middleware-guide.md,了解完整的中间件文档。
常见模式
| 模式 | 使用场景 | 关键技巧 |
|---|---|---|
| 计算值 | 派生数据 | 在选择器中计算:state.items.length |
| 异步操作 | API 调用 | set({ isLoading: true }) + try/catch |
| 重置 store | 退出登录、清空表单 | set(initialState) |
| 带参数的选择器 | 动态访问 | state.todos.find(t => t.id === id) |
| 多个 store | 分离关注点 | 分别调用 create() |
参见:references/common-patterns.md,查看完整实现。
高级主题
| 主题 | 使用场景 | 关键 API |
|---|---|---|
| Vanilla store | 非 React 场景、测试 | 来自 zustand/vanilla 的 createStore() |
| 自定义中间件 | 日志记录、时间戳 | 包装 StateCreator |
| Immer | 可变更新语法 | immer() 中间件 |
| 订阅 | 副作用 | store.subscribe() |
参见:references/advanced-topics.md,查看完整实现。
打包资源
| 类型 | 文件 |
|---|---|
| 模板 | basic-store.ts、typescript-store.ts、persist-store.ts、slices-pattern.ts、devtools-store.ts、nextjs-store.ts、computed-store.ts、async-actions-store.ts |
| 参考资料 | middleware-guide.md、typescript-patterns.md、nextjs-hydration.md、migration-guide.md、known-issues.md、common-patterns.md、advanced-topics.md |
何时加载参考资料
| 参考资料 | 加载时机…… |
|---|---|
known-issues.md | 调试 hydration、TypeScript、无限循环或 slices 错误时 |
common-patterns.md | 实现计算值、异步操作或重置模式时 |
advanced-topics.md | 使用 Vanilla store、自定义中间件、Immer 或订阅时 |
middleware-guide.md | 配置 persist、devtools 或组合中间件时 |
typescript-patterns.md | 遇到复杂的类型推断问题或 StateCreator 问题时 |
nextjs-hydration.md | 遇到 Next.js SSR/hydration 问题时 |
migration-guide.md | 从 Redux、Context API 或 Zustand v4 迁移时 |
快速故障排除
| 问题 | 解决方案 |
|---|---|
| Store 更新未触发重新渲染 | 使用选择器:useStore(state => state.value),不要使用解构 |
| 中间件导致 TypeScript 错误 | 使用 create<T>()() 双括号写法 |
| persist 导致 hydration 错误 | 实现 _hasHydrated 标志模式 |
| DevTools 中未显示操作 | 传入操作名称:set(newState, undefined, 'actionName') |
| Store 意外重置 | HMR 会导致开发环境中的重置 |
依赖项
{ "dependencies": { "zustand": "^5.0.14", "react": "^18.0.0+" } }
兼容性:React 18+、React 19、TypeScript 5+、Next.js 14+、Vite 5+
官方文档:https://zustand.docs.pmnd.rs/ | GitHub:https://github.com/pmndrs/zustand