zustand-state-management
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseZustand State Management
Zustand 状态管理
Status: Production Ready ✅
Last Updated: 2025-11-21
Latest Version: zustand@5.0.8
Dependencies: React 18+, TypeScript 5+
状态:生产就绪 ✅
最后更新:2025-11-21
最新版本:zustand@5.0.8
依赖项:React 18+、TypeScript 5+
Quick Start (3 Minutes)
快速入门(3分钟)
1. Install Zustand
1. 安装 Zustand
bash
bun add zustand # preferredbash
bun add zustand # 推荐方式or: npm install zustand
或:npm install zustand
or: yarn add zustand
或:yarn add zustand
**Why Zustand?**
- Minimal API: Only 1 function to learn (`create`)
- No boilerplate: No providers, reducers, or actions
- TypeScript-first: Excellent type inference
- Fast: Fine-grained subscriptions prevent unnecessary re-renders
- Flexible: Middleware for persistence, devtools, and more
**为什么选择Zustand?**
- 极简API:只需学习一个函数(`create`)
- 无冗余模板:无需提供者(providers)、reducers或actions
- TypeScript优先:出色的类型推断能力
- 高性能:细粒度订阅避免不必要的重渲染
- 灵活性强:支持持久化、开发者工具等中间件2. Create Your First Store (TypeScript)
2. 创建你的第一个Store(TypeScript)
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 }),
}))CRITICAL: Notice the double parentheses - this is required for TypeScript with middleware.
create<T>()()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 }),
}))重要提示:注意这里的双重括号 - 这是TypeScript结合中间件使用时的必填语法。
create<T>()()3. Use Store in Components
3. 在组件中使用Store
tsx
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>
}Why this works:
- Components only re-render when their selected state changes
- No Context providers needed
- Selector function extracts specific state slice
tsx
import { useBearStore } from './store'
function BearCounter() {
const bears = useBearStore((state) => state.bears)
return <h1>{bears} 只熊在这里...</h1>
}
function Controls() {
const increase = useBearStore((state) => state.increase)
return <button onClick={() => increase(1)}>添加一只熊</button>
}工作原理:
- 组件仅在其选中的状态发生变化时才会重渲染
- 无需Context提供者
- 通过选择器函数提取特定的状态切片
The 3-Pattern Setup Process
三种模式的设置流程
Pattern 1: Basic Store (JavaScript)
模式1:基础Store(JavaScript)
For simple use cases without TypeScript:
javascript
import { create } from 'zustand'
const useStore = create((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
decrement: () => set((state) => ({ count: state.count - 1 })),
}))When to use:
- Prototyping
- Small apps
- No TypeScript in project
适用于不使用TypeScript的简单场景:
javascript
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
Pattern 2: TypeScript Store (Recommended)
模式2:TypeScript Store(推荐)
For production apps with type safety:
typescript
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 })),
}))Key Points:
- Separate interface for state + actions
- Use syntax (currying for middleware)
create<T>()() - Full IDE autocomplete and type checking
适用于需要类型安全的生产应用:
typescript
import { create } from 'zustand'
// 定义Store接口
interface CounterStore {
count: number
increment: () => void
decrement: () => void
}
// 创建带类型的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自动补全和类型检查
Pattern 3: Persistent Store
模式3:持久化Store
For state that survives page reloads:
typescript
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
},
),
)Why this matters:
- State automatically saved to localStorage
- Restored on page reload
- Works with sessionStorage too
- Handles serialization automatically
适用于需要在页面刷新后保留的状态:
typescript
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', // localStorage中的唯一名称
storage: createJSONStorage(() => localStorage), // 可选:默认使用localStorage
},
),
)重要性:
- 状态自动保存到localStorage
- 页面刷新时自动恢复
- 同样支持sessionStorage
- 自动处理序列化
Critical Rules
关键规则
Always Do
务必遵守
✅ Use (double parentheses) in TypeScript for middleware compatibility
✅ Define separate interfaces for state and actions
✅ Use selector functions to extract specific state slices
✅ Use with updater functions for derived state:
✅ Use unique names for persist middleware storage keys
✅ Handle Next.js hydration with flag pattern
✅ Use for selecting multiple values
✅ Keep actions pure (no side effects except state updates)
create<T>()()setset((state) => ({ count: state.count + 1 }))hasHydratedshallow✅ 在TypeScript中使用 (双重括号)以兼容中间件
✅ 为状态和动作单独定义接口
✅ 使用选择器函数提取特定的状态切片
✅ 对派生状态使用带更新器函数的 :
✅ 为持久化中间件的存储键使用唯一名称
✅ 使用 标记模式处理Next.js的hydration
✅ 选择多个值时使用
✅ 保持动作纯净(除状态更新外无副作用)
create<T>()()setset((state) => ({ count: state.count + 1 }))hasHydratedshallowNever Do
切勿执行
❌ Use (single parentheses) in TypeScript - breaks middleware types
❌ Mutate state directly: - use immutable updates
❌ Create new objects in selectors: - causes infinite renders
❌ Use same storage name for multiple stores - causes data collisions
❌ Access localStorage during SSR without hydration check
❌ Use Zustand for server state - use TanStack Query instead
❌ Export store instance directly - always export the hook
create<T>(...)set((state) => { state.count++; return state })useStore((state) => ({ a: state.a }))❌ 在TypeScript中使用 (单括号)- 会破坏中间件类型
❌ 直接修改状态: - 使用不可变更新
❌ 在选择器中创建新对象: - 会导致无限渲染
❌ 为多个Store使用相同的存储名称 - 会导致数据冲突
❌ 在SSR期间未进行hydration检查就访问localStorage
❌ 使用Zustand管理服务端状态 - 改用TanStack Query
❌ 直接导出Store实例 - 始终导出钩子
create<T>(...)set((state) => { state.count++; return state })useStore((state) => ({ a: state.a }))Known Issues Prevention (5 Issues)
已知问题预防(5个问题)
| Issue | Error | Quick Fix |
|---|---|---|
| #1 Hydration mismatch | "Text content does not match" | Use |
| #2 TypeScript inference | Types break with middleware | Use |
| #3 Import error | "createJSONStorage not exported" | Upgrade to zustand@5.0.8+ |
| #4 Infinite loop | Browser freezes | Use |
| #5 Slices types | StateCreator types fail | Explicit |
Most Critical - TypeScript double parentheses:
typescript
// ❌ WRONG: create<T>((set) => ...)
// ✅ CORRECT: create<T>()((set) => ...)See: for complete solutions with code examples.
references/known-issues.md| 问题 | 错误信息 | 快速修复 |
|---|---|---|
| #1 Hydration 不匹配 | "文本内容不匹配" | 使用 |
| #2 TypeScript 类型推断 | 使用中间件时类型失效 | 使用 |
| #3 导入错误 | "createJSONStorage 未导出" | 升级到 zustand@5.0.8+ |
| #4 无限循环 | 浏览器冻结 | 使用 |
| #5 切片类型 | StateCreator 类型失效 | 显式声明 |
最关键 - TypeScript双重括号:
typescript
// ❌ 错误写法:create<T>((set) => ...)
// ✅ 正确写法:create<T>()((set) => ...)参考: 包含完整的代码示例解决方案。
references/known-issues.mdMiddleware Configuration
中间件配置
typescript
import { create } from 'zustand'
import { devtools, persist } from 'zustand/middleware'
const useStore = create<MyStore>()(
devtools(
persist(
(set) => ({ /* store definition */ }),
{ name: 'my-storage' },
),
{ name: 'MyStore' },
),
)| Middleware | Purpose | Import |
|---|---|---|
| localStorage/sessionStorage | |
| Redux DevTools integration | |
| Mutable update syntax | |
Order matters: shows persist actions in DevTools.
devtools(persist(...))See: for complete middleware documentation.
references/middleware-guide.mdtypescript
import { create } from 'zustand'
import { devtools, persist } from 'zustand/middleware'
const useStore = create<MyStore>()(
devtools(
persist(
(set) => ({ /* Store定义 */ }),
{ name: 'my-storage' },
),
{ name: 'MyStore' },
),
)| 中间件 | 用途 | 导入路径 |
|---|---|---|
| localStorage/sessionStorage持久化 | |
| Redux DevTools集成 | |
| 可变更新语法 | |
顺序很重要: 会在DevTools中显示持久化动作。
devtools(persist(...))参考: 包含完整的中间件文档。
references/middleware-guide.mdCommon Patterns
常见模式
| Pattern | Use Case | Key Technique |
|---|---|---|
| Computed values | Derived data | Compute in selector: |
| Async actions | API calls | |
| Reset store | Logout, form clear | |
| Selector with params | Dynamic access | |
| Multiple stores | Separation of concerns | Create separate |
See: for complete implementations.
references/common-patterns.md| 模式 | 适用场景 | 核心技巧 |
|---|---|---|
| 计算值 | 派生数据 | 在选择器中计算: |
| 异步动作 | API调用 | |
| 重置Store | 登出、表单清空 | |
| 带参数的选择器 | 动态访问 | |
| 多Store | 关注点分离 | 单独调用 |
参考: 包含完整的实现示例。
references/common-patterns.mdAdvanced Topics
进阶主题
| Topic | Use Case | Key API |
|---|---|---|
| Vanilla store | Non-React, testing | |
| Custom middleware | Logging, timestamps | Wrap |
| Immer | Mutable update syntax | |
| Subscriptions | Side effects | |
See: for complete implementations.
references/advanced-topics.md| 主题 | 适用场景 | 核心API |
|---|---|---|
| Vanilla Store | 非React环境、测试 | |
| 自定义中间件 | 日志、时间戳 | 包装 |
| Immer | 可变更新语法 | |
| 订阅 | 副作用 | |
参考: 包含完整的实现示例。
references/advanced-topics.mdBundled Resources
打包资源
| Type | Files |
|---|---|
| Templates | |
| References | |
| 类型 | 文件 |
|---|---|
| 模板 | |
| 参考文档 | |
When to Load References
何时加载参考文档
| Reference | Load When... |
|---|---|
| Debugging hydration, TypeScript, infinite loop, or slices errors |
| Implementing computed values, async actions, reset patterns |
| Vanilla stores, custom middleware, Immer, subscriptions |
| Configuring persist, devtools, or combining middlewares |
| Complex type inference issues, StateCreator problems |
| Next.js SSR/hydration problems |
| Migrating from Redux, Context API, or Zustand v4 |
| 参考文档 | 加载时机... |
|---|---|
| 调试hydration、TypeScript、无限循环或切片错误时 |
| 实现计算值、异步动作、重置模式时 |
| 使用Vanilla Store、自定义中间件、Immer或订阅时 |
| 配置持久化、开发者工具或组合中间件时 |
| 遇到复杂类型推断问题、StateCreator相关问题时 |
| 遇到Next.js SSR/hydration问题时 |
| 从Redux、Context API或Zustand v4迁移时 |
Quick Troubleshooting
快速故障排除
| Problem | Solution |
|---|---|
| Store updates don't trigger re-renders | Use selector: |
| TypeScript errors with middleware | Use |
| Hydration error with persist | Implement |
| Actions not showing in DevTools | Pass action name: |
| Store resets unexpectedly | HMR causes reset in development |
| 问题 | 解决方案 |
|---|---|
| Store更新未触发重渲染 | 使用选择器: |
| 使用中间件时出现TypeScript错误 | 使用 |
| 使用持久化时出现hydration错误 | 实现 |
| 动作未在DevTools中显示 | 传入动作名称: |
| Store意外重置 | 开发环境下HMR导致重置 |
Dependencies
依赖项
json
{ "dependencies": { "zustand": "^5.0.8", "react": "^18.0.0+" } }Compatibility: React 18+, React 19, TypeScript 5+, Next.js 14+, Vite 5+
Official Docs: https://zustand.docs.pmnd.rs/ | GitHub: https://github.com/pmndrs/zustand
json
{ "dependencies": { "zustand": "^5.0.8", "react": "^18.0.0+" } }兼容性:React 18+、React 19、TypeScript 5+、Next.js 14+、Vite 5+