zustand-state-management

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Zustand 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  # preferred
bash
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
create<T>()()
- this is required for TypeScript with middleware.
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. 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
    create<T>()()
    syntax (currying for middleware)
  • 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
create<T>()()
(double parentheses) in TypeScript for middleware compatibility ✅ Define separate interfaces for state and actions ✅ Use selector functions to extract specific state slices ✅ Use
set
with updater functions for derived state:
set((state) => ({ count: state.count + 1 }))
✅ Use unique names for persist middleware storage keys ✅ Handle Next.js hydration with
hasHydrated
flag pattern ✅ Use
shallow
for selecting multiple values ✅ Keep actions pure (no side effects except state updates)
✅ 在TypeScript中使用
create<T>()()
(双重括号)以兼容中间件 ✅ 为状态和动作单独定义接口 ✅ 使用选择器函数提取特定的状态切片 ✅ 对派生状态使用带更新器函数的
set
set((state) => ({ count: state.count + 1 }))
✅ 为持久化中间件的存储键使用唯一名称 ✅ 使用
hasHydrated
标记模式处理Next.js的hydration ✅ 选择多个值时使用
shallow
✅ 保持动作纯净(除状态更新外无副作用)

Never Do

切勿执行

❌ Use
create<T>(...)
(single parentheses) in TypeScript - breaks middleware types ❌ Mutate state directly:
set((state) => { state.count++; return state })
- use immutable updates ❌ Create new objects in selectors:
useStore((state) => ({ a: state.a }))
- 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

❌ 在TypeScript中使用
create<T>(...)
(单括号)- 会破坏中间件类型 ❌ 直接修改状态:
set((state) => { state.count++; return state })
- 使用不可变更新 ❌ 在选择器中创建新对象:
useStore((state) => ({ a: state.a }))
- 会导致无限渲染 ❌ 为多个Store使用相同的存储名称 - 会导致数据冲突 ❌ 在SSR期间未进行hydration检查就访问localStorage ❌ 使用Zustand管理服务端状态 - 改用TanStack Query ❌ 直接导出Store实例 - 始终导出钩子

Known Issues Prevention (5 Issues)

已知问题预防(5个问题)

IssueErrorQuick Fix
#1 Hydration mismatch"Text content does not match"Use
_hasHydrated
flag +
onRehydrateStorage
#2 TypeScript inferenceTypes break with middlewareUse
create<T>()()
double parentheses
#3 Import error"createJSONStorage not exported"Upgrade to zustand@5.0.8+
#4 Infinite loopBrowser freezesUse
shallow
or separate selectors
#5 Slices typesStateCreator types failExplicit
StateCreator<Combined, [], [], Slice>
Most Critical - TypeScript double parentheses:
typescript
// ❌ WRONG: create<T>((set) => ...)
// ✅ CORRECT: create<T>()((set) => ...)
See:
references/known-issues.md
for complete solutions with code examples.

问题错误信息快速修复
#1 Hydration 不匹配"文本内容不匹配"使用
_hasHydrated
标记 +
onRehydrateStorage
#2 TypeScript 类型推断使用中间件时类型失效使用
create<T>()()
双重括号
#3 导入错误"createJSONStorage 未导出"升级到 zustand@5.0.8+
#4 无限循环浏览器冻结使用
shallow
或拆分选择器
#5 切片类型StateCreator 类型失效显式声明
StateCreator<Combined, [], [], Slice>
最关键 - TypeScript双重括号:
typescript
// ❌ 错误写法:create<T>((set) => ...)
// ✅ 正确写法:create<T>()((set) => ...)
参考
references/known-issues.md
包含完整的代码示例解决方案。

Middleware 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' },
  ),
)
MiddlewarePurposeImport
persist
localStorage/sessionStorage
zustand/middleware
devtools
Redux DevTools integration
zustand/middleware
immer
Mutable update syntax
zustand/middleware/immer
Order matters:
devtools(persist(...))
shows persist actions in DevTools.
See:
references/middleware-guide.md
for complete middleware documentation.

typescript
import { create } from 'zustand'
import { devtools, persist } from 'zustand/middleware'

const useStore = create<MyStore>()(
  devtools(
    persist(
      (set) => ({ /* Store定义 */ }),
      { 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
包含完整的中间件文档。

Common Patterns

常见模式

PatternUse CaseKey Technique
Computed valuesDerived dataCompute in selector:
state.items.length
Async actionsAPI calls
set({ isLoading: true })
+ try/catch
Reset storeLogout, form clear
set(initialState)
Selector with paramsDynamic access
state.todos.find(t => t.id === id)
Multiple storesSeparation of concernsCreate separate
create()
calls
See:
references/common-patterns.md
for complete implementations.

模式适用场景核心技巧
计算值派生数据在选择器中计算:
state.items.length
异步动作API调用
set({ isLoading: true })
+ try/catch
重置Store登出、表单清空
set(initialState)
带参数的选择器动态访问
state.todos.find(t => t.id === id)
多Store关注点分离单独调用
create()
创建多个Store
参考
references/common-patterns.md
包含完整的实现示例。

Advanced Topics

进阶主题

TopicUse CaseKey API
Vanilla storeNon-React, testing
createStore()
from
zustand/vanilla
Custom middlewareLogging, timestampsWrap
StateCreator
ImmerMutable update syntax
immer()
middleware
SubscriptionsSide effects
store.subscribe()
See:
references/advanced-topics.md
for complete implementations.

主题适用场景核心API
Vanilla Store非React环境、测试
zustand/vanilla
中的
createStore()
自定义中间件日志、时间戳包装
StateCreator
Immer可变更新语法
immer()
中间件
订阅副作用
store.subscribe()
参考
references/advanced-topics.md
包含完整的实现示例。

Bundled Resources

打包资源

TypeFiles
Templates
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
References
middleware-guide.md
,
typescript-patterns.md
,
nextjs-hydration.md
,
migration-guide.md
,
known-issues.md
,
common-patterns.md
,
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

When to Load References

何时加载参考文档

ReferenceLoad When...
known-issues.md
Debugging hydration, TypeScript, infinite loop, or slices errors
common-patterns.md
Implementing computed values, async actions, reset patterns
advanced-topics.md
Vanilla stores, custom middleware, Immer, subscriptions
middleware-guide.md
Configuring persist, devtools, or combining middlewares
typescript-patterns.md
Complex type inference issues, StateCreator problems
nextjs-hydration.md
Next.js SSR/hydration problems
migration-guide.md
Migrating from Redux, Context API, or Zustand v4

参考文档加载时机...
known-issues.md
调试hydration、TypeScript、无限循环或切片错误时
common-patterns.md
实现计算值、异步动作、重置模式时
advanced-topics.md
使用Vanilla Store、自定义中间件、Immer或订阅时
middleware-guide.md
配置持久化、开发者工具或组合中间件时
typescript-patterns.md
遇到复杂类型推断问题、StateCreator相关问题时
nextjs-hydration.md
遇到Next.js SSR/hydration问题时
migration-guide.md
从Redux、Context API或Zustand v4迁移时

Quick Troubleshooting

快速故障排除

ProblemSolution
Store updates don't trigger re-rendersUse selector:
useStore(state => state.value)
not destructuring
TypeScript errors with middlewareUse
create<T>()()
double parentheses
Hydration error with persistImplement
_hasHydrated
flag pattern
Actions not showing in DevToolsPass action name:
set(newState, undefined, 'actionName')
Store resets unexpectedlyHMR causes reset in development

问题解决方案
Store更新未触发重渲染使用选择器:
useStore(state => state.value)
而非解构赋值
使用中间件时出现TypeScript错误使用
create<T>()()
双重括号
使用持久化时出现hydration错误实现
_hasHydrated
标记模式
动作未在DevTools中显示传入动作名称:
set(newState, undefined, 'actionName')
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+

json
{ "dependencies": { "zustand": "^5.0.8", "react": "^18.0.0+" } }
兼容性:React 18+、React 19、TypeScript 5+、Next.js 14+、Vite 5+