Zustand:一个让 React 状态管理“返璞归真”的革命者

4 阅读6分钟

你还记得第一次写 React 项目时,为了实现一个简单的“待办事项”功能,被迫引入 Redux、配置 store、写 action creators、搞 reducers、连 connect……最后发现:

“我只是想勾个 checkbox 而已,为什么要动用三军?”

时代变了。

如今,我们不再需要为“状态”而向复杂妥协。
有一个轻如鸿毛、却强如引擎的工具,正在悄悄改变 React 开发者的日常 ——

👉 Zustand —— 中文谐音“足矣”,仿佛在说:“有我,就够了。”


🧩 一、React 状态管理的进化史:从“造火箭”到“骑单车”

让我们先回顾一下 React 状态管理的三个时代:

1.0 时代:Redux 统治天下

  • ✅ 功能强大,适合大型项目
  • ❌ 模板代码太多,“搬砖感”强烈
  • 📦 配置成本高,新手劝退率 90%

就像你要去便利店买瓶水,结果被要求先考驾照、买辆车、建条公路。

2.0 时代:Context + useReducer

  • ✅ 官方方案,无需第三方库
  • ❌ 性能问题频出,容易引发全量重渲染
  • 🔁 状态更新像“广播”,谁都在听,谁都不能不听

3.0 时代:Zustand 登场 —— 极简主义的胜利

它不做加法,而是做减法:

“状态管理的本质,不是组织代码结构,而是让数据流动得更自然。”

于是,Zustand 带来了三个字:
🎯 简单、直接、自由


💡 二、Zustand 的核心理念:把状态还给开发者

Zustand 不是另一个“框架”,它更像是一个 状态管理的“最小可行产品”(MVP)

它的设计哲学可以总结为四句话:

  • 状态就是一个 JavaScript 对象
  • 修改状态就是调用一个函数
  • 全局共享?不需要 Context 传递
  • 类型安全?天生支持 TypeScript

它解决了什么痛点?

传统方式的问题Zustand 如何解决
要写 Action Type、Reducer 分别处理逻辑直接在 store 里写函数
跨组件传状态要层层透传或用 Contextstore 全局可访问
更新状态要 dispatch(action)直接调用 store.toggleTodo(id)
持久化要手动存 localStorage内置 middleware 支持持久化

🛠️ 三、举个例子:一个 Todo 应用的“极简革命”

假设我们要做一个待办事项应用。需求很简单:

  • 添加任务
  • 切换完成状态
  • 删除任务
  • 关闭页面后数据不丢失

换成以前,你可能已经开始想:“要不要拆模块?要不要抽象 action?”

而在 Zustand 的世界里,这一切变得像写普通函数一样自然。

✅ 你的 Store 长这样:

const useTodoStore = create<TodoState>()(
  persist(
    (set) => ({
      todos: [],
      addTodo: (text) =>
        set((state) => ({
          todos: [...state.todos, { id: Date.now(), text, completed: false }],
        })),
      toggleTodo: (id) =>
        set((state) => ({
          todos: state.todos.map((todo) =>
            todo.id === id ? { ...todo, completed: !todo.completed } : todo
          ),
        })),
      removeTodo: (id) =>
        set((state) => ({
          todos: state.todos.filter((todo) => todo.id !== id),
        })),
    }),
    { name: 'todo-storage' }
  )
);

看到了吗?没有 dispatch,没有 reducer switch,没有 connect
所有操作都是同步函数调用,逻辑清晰到几乎可以朗读出来。

“当我点击添加时,就往 todos 数组里 push 一条新数据。”
—— 这不正是我们最初想要的编程体验吗?


🔌 四、persist 中间件:让数据“记住自己”

最惊艳的是这一行:

{ name: 'todo-storage' }

加上这个配置,你的 todos 就自动存进了 localStorage
刷新页面?数据还在。
关机重启?照样回来。

这不是魔法,而是 “合理默认值” + “极简 API” 的胜利。

你可以把它理解为:

Zustand 说:“我知道你迟早要用持久化,所以我提前帮你装好了插座,插上就行。”

而且它还是类型安全的!你在 TypeScript 中使用 useTodoStore,编辑器能自动推导出所有字段和方法,不会有 any 的尴尬。


🎣 五、基于 Hooks 的思想重构状态管理

Zustand 最深刻的革新,其实是它的架构思想

它不像 Redux 是“类 Flux 架构”,而是完全拥抱了 React 的现代范式 —— Hooks 思维

这意味着:

  • Store 可以像 useState 一样按需使用
  • 不再需要 Provider 套来套去
  • 组件只订阅它关心的状态片段(自动 GC)
  • 可以轻松拆分多个小 store,避免“大仓库综合症”

就像你不会因为要做一道菜就建个中央厨房,
你也不该因为几个状态就搭一套复杂的管理系统

Zustand 让“全局状态”变得像 useState 一样轻量,却又具备跨组件能力。


🆚 六、Zustand vs 其他方案:为什么越来越多人选择它?

方案包体积学习成本类型支持适用场景
Redux Toolkit~7KB超大型项目,需严格追踪
Context0小型共享状态
Recoil/Jotai~5KB原子化状态管理
Zustand~4.5KB极低极好绝大多数中小型项目

GitHub 上 zustand 的 trending 曲线在过去两年一路飙升,不是偶然。

它击中了一个关键空白点:

“我需要一个比 Context 更强大、比 Redux 更轻便的方案。”

而 Zustand 正好站在那个黄金平衡点上。


🧠 七、我的思考:状态管理的未来是“去架构化”

随着 React Server Components、Suspense、Signals 等新范式的兴起,
我们越来越意识到:

状态本身不该成为开发负担。

Zustand 的流行,反映了一种趋势:
开发者不再愿意为“管理状态”而花大量时间设计架构。
我们想要的是:专注业务逻辑,而不是组织代码结构

这也是为什么越来越多的新项目(包括 Vercel、Turborepo 的周边工具)都开始采用 Zustand。

因为它不做多余的事,只做一件事,并且做到极致:

让状态流动得更自然一点。


🚀 八、如何开始使用 Zustand?

安装只需一行:

npm install zustand

然后创建你的第一个 store:

import { create } from 'zustand';

interface BearState {
  bears: number;
  increase: () => void;
}

const useBearStore = create<BearState>((set) => ({
  bears: 0,
  increase: () => set((state) => ({ bears: state.bears + 1 })),
}));

在组件中使用:

function BearCounter() {
  const { bears } = useBearStore();
  return <h1>{bears} 只熊</h1>;
}

function Controls() {
  const { increase } = useBearStore();
  return <button onClick={increase}>喂食一只熊</button>;
}

就这么简单。没有仪式感,只有生产力。


🌈 结语:有时候,少就是多

在这个“微服务、中间件、DSL”满天飞的时代,
Zustand 像是一股清流,提醒我们:

技术的终极目标不是炫技,而是让人更自由地表达想法。

当你不再纠结“这个 action 该怎么命名”,
当你可以直接写下“addTodo”并立刻生效,
那一刻,你会感受到一种久违的——

编程的纯粹快乐。


如果你也曾被状态管理折磨过,
如果你也渴望一种更轻盈的开发方式,
不妨试试 Zustand。

也许,它真的就是你一直在找的那个答案。

#React #Zustand #状态管理 #TypeScript #前端开发 #掘金精品 #架构设计 #useStore #极简主义