Zustand logo

Zustand

React 状态管理的"熊之必需品"——极简 Hooks API、无 Provider、无样板代码,用不到 1 KB 的体积覆盖从小型组件到企业级应用的全部状态场景。

精选工具状态管理ReactHooks极简

Zustand 是 2024-2026 年增长最快的 React 状态管理库,采用单一 Store + Hooks 选择器模型。无需 Provider 包裹,bundle 仅约 1.1KB,npm 周下载量超 3600 万,已超越 Redux 成为 React 生态下载量最高的状态管理库,是 2026 年 React 状态管理的默认选择。

Zustand

React 状态管理的"熊之必需品"——极简 Hooks API、无 Provider、无样板代码,用不到 1 KB 的体积覆盖从小型组件到企业级应用的全部状态场景。


技术简介说明

Zustand(德语"状态"之意)是由 pmndrs 维护的 React 状态管理库,由 Andrew Clark 的 former collaborator Daishi Kato 与 Paul Henschel 等核心成员共同打造。它采用单一 Store + Hooks 选择器模型管理全局状态——开发者通过 create 函数创建 store,在组件内以 useStore(selector) 的方式订阅所需状态片段,框架自动完成最小化重渲染。

Zustand 的设计哲学是"做减法":不需要 Provider 包裹、不需要 action/reducer 模板、不需要 context 嵌套。一个 store 就是一个普通的 JavaScript 对象和一组更新函数,通过 useState 一样的 Hook 在组件中使用。这种"几乎不存在"的学习成本使得 Zustand 成为 2024-2026 年增长最快的 React 状态管理方案——npm 周下载量从 2024 年初的 1200 万攀升至 2026 年中的 3600 万+,一举超越 Redux 成为 React 生态下载量最高的状态管理库。

Zustand 与 Jotai、Valtio 同属 pmndrs 生态,但定位互补:Zustand 是"单 store 自顶向下"、Jotai 是"多 atom 自底向上"、Valtio 是"Proxy 可变模式"。三者可以共存于同一个项目中,分别处理不同粒度的状态需求。截至 2026 年 7 月,Zustand 最新版本为 v5.0.14,GitHub 星标超过 58.4k


基本信息

项目信息
官网https://zustand.docs.pmnd.rs
GitHubhttps://github.com/pmndrs/zustand
npmhttps://www.npmjs.com/package/zustand
最新版本v5.0.14(2026-05-28 发布)
LicenseMIT
GitHub Stars~58.4k
周下载量~3600 万
Bundle Size~1.1 kB(gzip)
TypeScript原生支持,源码 97.9% TypeScript
主要维护者Daishi Kato、Paul Henschel(pmndrs 团队)
所属组织pmndrs
Node.js 要求>= 18
React 要求>= 18(完整支持 React 19)

快速上手

安装

# npm
npm install zustand
 
# yarn
yarn add zustand
 
# pnpm
pnpm add zustand
 
# bun
bun add zustand

基础配置

Zustand 不需要 任何 Provider、不需要包裹 <App />。直接创建 store,直接在任何组件中使用:

// 无需全局配置,无需 Provider
// 直接创建 store 即可使用
import { create } from 'zustand'
 
const useStore = create((set) => ({
  count: 0,
  increment: () => set((state) => ({ count: state.count + 1 })),
}))

最小示例

import { create } from 'zustand'
 
// 1. 创建 store:state + actions 在一个函数内
interface BearState {
  bears: number
  increase: () => void
  reset: () => void
}
 
const useBearStore = create<BearState>()((set) => ({
  bears: 0,
  increase: () => set((state) => ({ bears: state.bears + 1 })),
  reset: () => set({ bears: 0 }),
}))
 
// 2. 在组件中使用:通过 selector 订阅所需状态
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}>One more</button>
}
 
// 3. 在 React 组件树中使用(无需 Provider)
function App() {
  return (
    <>
      <BearCounter />
      <Controls />
    </>
  )
}

核心概念与架构

单一 Store 模型

Zustand 采用单 store + selector 架构。整个应用可以只有一个 store(也可以有多个独立 store),store 是一个包含状态和 actions 的 JavaScript 对象。这与 Redux 的单 store 理念一致,但省去了 reducer、action creators、dispatch 等大量样板代码。

┌─────────────────────────────────────┐
│           Zustand Store             │
│  ┌───────────┐  ┌────────────────┐  │
│  │   State   │  │    Actions     │  │
│  │  (data)   │  │  (set/reset)   │  │
│  └─────┬─────┘  └───────┬────────┘  │
│        │   set(state)    │           │
│        └─────────────────┘           │
│               │                      │
│    useSyncExternalStore              │
│               │                      │
│  ┌────────────▼────────────────┐     │
│  │  Selector → Component 订阅   │     │
│  │  (最小化重渲染)               │     │
│  └─────────────────────────────┘     │
└─────────────────────────────────────┘

不可变状态 + set() 更新

Zustand 使用不可变状态模型(Immutable State Model),所有状态更新都通过 set() 函数完成,内部执行对象展开(spread)生成新引用。这与 Redux 的理念一致,但 API 极其简洁:

  • set(partial) — 合并部分状态
  • set(state => partial, replace?) — 函数式更新
  • replace: true — 完全替换状态而非合并

外部存储 + useSyncExternalStore

Zustand 的 store 是 React 外部的独立对象,不依赖 React 的 Context 机制。它使用 React 18 内置的 useSyncExternalStore Hook 实现与 React 并发模式的兼容——这是 Zustand 要求 React >= 18 的根本原因。

中间件系统

Zustand 的中间件(Middleware)是链式组合的功能增强层,采用函数式组合模式:

create(
  devtools(          // 4. Redux DevTools 集成
    persist(          // 3. 本地持久化
      immer(          // 2. 可变更新语法
        (set, get) => ({ ... })  // 1. 基础 store
      )
    )
  )
)

核心特性

1. 极简 API

整个核心 API 只有 createsetget 三个函数。没有 Provider、没有 action、没有 reducer、没有 dispatch。一个 store 就是一个 Hook。

2. 无 Provider 包裹

基于 useSyncExternalStore 的外部存储模型,不需要在组件树顶层包裹任何 Context Provider。任何组件都可以直接使用 store。

3. Selector 精细订阅

通过 selector 函数精确订阅所需状态片段,框架使用 Object.is 做浅比较,只有选中值变化时才触发重渲染:

// 只订阅 count,其他状态变化不会触发此组件重渲染
const count = useStore((state) => state.count)

4. 中间件生态

内置 devtoolspersistsubscribeWithSelectorcombinetemporal 等中间件,支持链式组合。社区提供了 immerredux(兼容 Redux reducer)、query 等扩展中间件。

5. TypeScript 一等支持

源码 97.9% 为 TypeScript,提供完整的类型推断。v5 进一步收紧了类型安全性,setStatereplace 参数有严格类型检查。

6. 多平台兼容

支持 React DOM、React Native、React Three Fiber(r3f)、Preact 等多种渲染器。Store 本身是纯 JavaScript 对象,也可在非 React 环境(Vue、Svelte、Vanilla JS)中使用。

7. 异步操作原生支持

actions 中可以直接使用 async/await,无需任何额外配置:

const useStore = create((set) => ({
  fetchData: async () => {
    const data = await api.getData()
    set({ data })
  },
}))

8. Store 组合与切片

支持将 store 拆分为多个独立的切片(slice),每个切片管理一部分状态和 actions,适合大型应用模块化组织。

9. 持久化存储

persist 中间件内置支持 localStorage、sessionStorage、IndexedDB 等多种存储后端,支持版本迁移(migrate)和部分持久化(partialize)。

10. DevTools 集成

devtools 中间件无缝接入 Redux DevTools,支持时间旅行调试、状态快照、action 日志等。


生态图

                        Zustand 生态
                            │
    ┌───────────────────────┼───────────────────────┐
    │                       │                       │
  官方中间件             社区扩展              开发者工具
    │                       │                       │
    ├─ devtools             ├─ zustand-computed     ├─ Redux DevTools
    ├─ persist              ├─ zustand/middleware   ├─ Zustand Explorer
    ├─ subscribeWithSelector│   (immer, redux)     ├─ Chrome Extension
    ├─ combine              ├─ zustand-x          │
    ├─ temporal             ├─ zustand-query       集成方案
    │                       ├─ zustand-form        │
    │                       └─ zustand-router      ├─ Next.js
    │                                            ├─ React Native
  官方调试工具                                   ├─ React Three Fiber
    │                                            ├─ Remix
    └─ zustand-demo                              ├─ Tauri
                                                 └─ Electron

核心生态包

包名说明
zustand核心库
zustand/middleware官方中间件集合(devtools、persist 等)
zustand/traditionalcreateWithEqualityFn(v5 迁移兼容)
zustand/shallowuseShallow Hook(浅比较选择器)
zustand/middleware/immerImmer 中间件,支持可变更新语法
zustand/middleware/reduxRedux reducer 兼容中间件

适用场景

1. 中小型项目的全局状态管理

Zustand 的极简 API 和零配置特性使其成为中小型项目的首选。无需 Provider、无需样板代码,几分钟内即可完成状态管理搭建。

2. 替代 Redux 的现代方案

对于已经熟悉 Redux 但厌倦了样板代码的团队,Zustand 提供了类似的心智模型(单 store、不可变更新、DevTools)但代码量减少 70%+。

3. 跨组件共享状态

需要多个不相关组件共享同一份状态(用户认证、主题、购物车等)时,Zustand 的无 Provider 模型使得状态访问极其便捷。

4. 需要持久化的状态

persist 中间件内置支持 localStorage、IndexedDB 等,适合需要状态持久化的场景(表单草稿、用户偏好设置等)。

5. 服务端状态与缓存

结合 zustand-query 或自定义异步 actions,可以处理服务端状态缓存,适合 Next.js、Remix 等 SSR 框架。

6. 3D / Canvas / 游戏类应用

Zustand 在 React Three Fiber(r3f)社区中使用极其广泛,适合需要高频更新且不影响 React 渲染性能的场景。

7. 多 Store / 模块化架构

大型应用可以创建多个独立 store,每个 store 负责一个业务领域,避免单 store 过于庞大。


开发与工程化

TypeScript 配置

import { create } from 'zustand'
 
// 推荐:使用接口定义 store 类型
interface CounterState {
  count: number
  increment: () => void
  decrement: () => void
  reset: () => void
}
 
const useCounterStore = create<CounterState>()((set) => ({
  count: 0,
  increment: () => set((state) => ({ count: state.count + 1 })),
  decrement: () => set((state) => ({ count: state.count - 1 })),
  reset: () => set({ count: 0 }),
}))

Store 切片模式(Slice Pattern)

import { create } from 'zustand'
import { devtools, persist } from 'zustand/middleware'
import type { StateCreator } from 'zustand'
 
// 定义各切片
interface BearSlice {
  bears: number
  addBear: () => void
}
 
interface FishSlice {
  fishes: number
  addFish: () => void
}
 
// 各切片独立实现
const createBearSlice: StateCreator<
  BearSlice & FishSlice,
  [['zustand/devtools', never], ['zustand/persist', unknown]],
  [],
  BearSlice
> = (set) => ({
  bears: 0,
  addBear: () => set((state) => ({ bears: state.bears + 1 })),
})
 
const createFishSlice: StateCreator<
  BearSlice & FishSlice,
  [['zustand/devtools', never], ['zustand/persist', unknown]],
  [],
  FishSlice
> = (set) => ({
  fishes: 0,
  addFish: () => set((state) => ({ fishes: state.fishes + 1 })),
})
 
// 组合切片
const useStore = create<BearSlice & FishSlice>()(
  devtools(
    persist(
      (...a) => ({
        ...createBearSlice(...a),
        ...createFishSlice(...a),
      }),
      { name: 'animal-store' }
    )
  )
)

测试

import { act } from 'react'
import { useBearStore } from './store'
 
test('should increase bears', () => {
  // 重置 store 状态
  act(() => useBearStore.setState({ bears: 0 }))
 
  // 调用 action
  act(() => useBearStore.getState().increase())
 
  // 验证结果
  expect(useBearStore.getState().bears).toBe(1)
})

代码分割

// 动态导入 store,实现代码分割
const useHeavyStore = create(() => ({
  /* 大量状态 */
}))
 
// 在组件中懒加载
const HeavyComponent = lazy(() => import('./HeavyComponent'))

性能与安全

性能特性

维度表现
Bundle Size~1.1 kB(gzip),比 Redux 小约 7 倍
重渲染优化基于 selector + Object.is 的精细订阅,只订阅部分状态时其他状态变化不触发重渲染
渲染次数useState 几乎相同(1000 个订阅组件约 18ms)
内存占用极低,store 是纯 JavaScript 对象,无额外包装
并发安全基于 useSyncExternalStore,完整支持 React 18+ 并发模式
服务端渲染完整支持 SSR,支持流式渲染

性能优化要点

// ✅ 正确:使用 selector 精确订阅
const count = useStore((state) => state.count)
 
// ✅ 正确:使用 useShallow 避免对象引用变化
import { useShallow } from 'zustand/shallow'
const { count, text } = useStore(
  useShallow((state) => ({ count: state.count, text: state.text }))
)
 
// ❌ 避免:在组件内创建新函数引用
const filtered = useStore((state) => state.items.filter(i => i.active))
// ✅ 改用:外部选择器函数
const selectActiveItems = (state) => state.items.filter(i => i.active)
const filtered = useStore(selectActiveItems)

安全注意事项

  • Zustand 的 persist 中间件默认使用 JSON.stringify/parse,存储数据在 localStorage 中是明文的。敏感数据需要额外加密。
  • persist 中间件的 storage 选项支持自定义序列化逻辑,可以接入加密方案。
  • Zustand 本身不做状态校验,输入验证应在 actions 层实现。
  • 避免在 store 中存储不可序列化的对象(DOM 引用、循环引用对象等)。

技术对比

横向对比表

特性ZustandRedux ToolkitJotaiValtioMobXRecoil
模型单 Store单 Store原子化 (Atom)Proxy 可变可观察对象原子化 (Atom)
Bundle Size~1.1 kB~11 kB~4 kB~3 kB~16 kB~14 kB
学习曲线⭐ 极低⭐⭐⭐ 中等⭐⭐ 低⭐ 极低⭐⭐⭐ 中高⭐⭐⭐ 中等
Provider不需要需要不需要不需要不需要需要
可变/不可变不可变不可变不可变可变 (Proxy)可变 (Observable)不可变
TypeScript优秀优秀优秀良好优秀良好
DevToolsRedux DevToolsRedux DevTools独立 DevToolsChrome ExtensionMobX DevToolsRecoil DevTools
中间件丰富丰富基础有限丰富有限
SSR⚠️ 有限
React Native
并发模式⚠️⚠️
维护状态活跃活跃活跃活跃活跃已归档
周下载量 (2026)~3600 万~600 万~530 万~160 万~250 万
GitHub Stars~58.4k~61k~21.2k~10.2k~27k

选型建议

  • Zustand — 大多数项目的最佳选择。API 最简单、bundle 最小、无需 Provider、适合从小组件到大型应用的完整场景。
  • Redux Toolkit — 大型团队需要严格规范、时间旅行调试、完善的 DevTools 和可预测的 action/reducer 流时使用。
  • Jotai — 复杂相互依赖的状态(如表单构建器、派生状态链),原子化模型更适合自底向上组合。
  • Valtio — 偏好可变更新语法、类 Vue/MobX 的开发体验时使用。
  • MobX — 已有 MobX 代码库的项目继续使用;新项目在 React 场景下通常优先 Zustand/Valtio。
  • Recoil — 已被 Meta 归档(archived),不建议新项目使用,现有项目建议迁移至 Jotai 或 Zustand。

最佳实践

1. 使用 Selector 精确订阅

// ✅ 只订阅需要的字段
const count = useStore((state) => state.count)
 
// ✅ 组合多个 selector
const count = useStore(useShallow((s) => s.count))
const name = useStore(useShallow((s) => s.name))
 
// ❌ 避免订阅整个 store
const store = useStore() // 任何状态变化都会触发重渲染

2. 将 Actions 与 State 放在一起

// ✅ 推荐:actions 和 state 在同一个 store 定义中
const useStore = create((set) => ({
  count: 0,
  increment: () => set((s) => ({ count: s.count + 1 })),
}))
 
// ❌ 避免:actions 定义在组件内部
function Counter() {
  const increment = () => useStore.setState((s) => ({ count: s.count + 1 }))
}

3. 使用 Immer 中间件简化深层更新

import { create } from 'zustand'
import { immer } from 'zustand/middleware/immer'
 
const useStore = create(
  immer((set) => ({
    users: [],
    updateUser: (id, name) =>
      set((state) => {
        const user = state.users.find((u) => u.id === id)
        if (user) user.name = name // 直接可变更新,Immer 自动生成不可变副本
      }),
  }))
)

4. 使用 persist 中间件持久化状态

import { create } from 'zustand'
import { persist } from 'zustand/middleware'
 
const useAuthStore = create(
  persist(
    (set) => ({
      token: null,
      setToken: (token) => set({ token }),
    }),
    {
      name: 'auth-storage',        // localStorage key
      partialize: (state) => ({    // 只持久化需要的字段
        token: state.token,
      }),
    }
  )
)

5. 组件外访问 Store

// 在 React 组件外部(如 API 拦截器、工具函数)访问 store
const token = useAuthStore.getState().token
useAuthStore.setState({ token: newToken })
 
// 订阅状态变化(如同步到其他系统)
const unsubscribe = useAuthStore.subscribe(
  (state) => state.token,
  (token) => {
    console.log('Token changed:', token)
  }
)

6. v5 迁移注意事项

// ✅ 使用 useShallow 处理返回新引用的 selector
import { useShallow } from 'zustand/shallow'
const { a, b } = useStore(useShallow((s) => ({ a: s.a, b: s.b })))
 
// ✅ 保持 fallback 值引用稳定
const NOOP = () => {}
const action = useStore((s) => s.action ?? NOOP)
 
// ❌ v4 中可用但 v5 移除的写法
const data = useStore(selector, isEqual) // 自定义相等函数已移除

技术局限与边界

1. 无内置派生状态

Zustand 没有像 Jotai 的 atom((get) => ...) 或 MobX 的 computed 那样的内置派生状态机制。派生状态需要在 selector 中手动计算,或在 store 中手动维护:

// 手动维护派生状态
const useStore = create((set, get) => ({
  items: [],
  activeCount: 0, // 需要手动同步
  addItem: (item) => set((s) => ({
    items: [...s.items, item],
    activeCount: s.activeCount + (item.active ? 1 : 0),
  })),
}))

2. 无原子化组合

Zustand 是单 store 模型,不支持像 Jotai 那样自底向上组合独立的原子状态。需要原子化组合时应选择 Jotai。

3. Selector 返回新引用的陷阱

v5 严格要求 selector 返回稳定引用。每次返回新数组/对象会导致无限循环:

// ❌ 会导致无限循环
const data = useStore((s) => [s.a, s.b])
// ✅ 必须使用 useShallow
const data = useStore(useShallow((s) => [s.a, s.b]))

4. 无内置时间旅行调试

Zustand 通过 devtools 中间件接入 Redux DevTools,但不像 Redux 那样原生支持完整的时间旅行(time-travel)。temporal 中间件提供有限的撤销/重做能力。

5. 大型应用需要手动组织

Zustand 不提供官方目录结构或代码组织约定。大型应用需要自行设计切片模式(slice pattern)、模块边界和 store 拆分策略。

6. 不适合纯函数式/事件溯源架构

Zustand 的 set() 是命令式的状态更新,不适合需要完整 action 日志和事件溯源(Event Sourcing)的场景。这类场景更适合 Redux。

7. React 版本限制

v5 要求 React >= 18(因为依赖 useSyncExternalStore)。如果项目仍使用 React 17,需要停留在 v4 或使用 use-sync-external-store shim。


学习资源

官方资源

教程与文章

视频

对比分析


2026 年现状

市场地位

截至 2026 年中,Zustand 已经成为 React 生态下载量最高的状态管理库,周下载量超过 3600 万次,远超 Redux Toolkit(~600 万)和 Jotai(~530 万)。在 2024-2025 年间,Zustand 完成了对 Redux 的"静默超越"——不是通过激进的营销,而是通过开发者口口相传的"简单就是好"。

社区活跃度

  • GitHub Stars:58.4k(2026 年 7 月)
  • Open Issues:仅 2 个(极度稳定的代码库)
  • npm 周下载量:~3600 万
  • 104 个正式版本发布

技术趋势

  • React 19 兼容:Zustand v5 完整支持 React 19 的并发特性,包括 use() Hook 和 Server Components。
  • 无重大新特性计划:v5 是一个"清理版"(cleanup release),核心 API 已经稳定。社区预期 v6 可能在 React 新特性成熟后推出。
  • pmndrs 生态协同:Zustand 与 Jotai(原子化)、Valtio(Proxy)、Koota(ECS)在 pmndrs 生态中各自定位清晰,互不竞争。
  • 企业采用加速:越来越多的中大型企业从 Redux 迁移到 Zustand,特别是在新项目和技术栈升级中。
  • Signals 的潜在竞争:Preact Signals 和 TC39 Signals Proposal 是 2026 年的新竞争者,但目前 Zustand 的生态成熟度和社区规模仍占据绝对优势。

选型结论

Zustand 是 2026 年 React 状态管理的默认选择。除非你有特殊需求(原子化组合 → Jotai、Proxy 可变 → Valtio、严格规范 → Redux Toolkit),否则 Zustand 是最简单、最高效的起点。


📅 文档更新时间:2026-07-07
📦 数据来源:GitHub、npm、pmndrs 官方博客、社区对比文章
🔗 基于 Zustand v5.0.14 编写