
Redux曾经是React生态的"国王",但最近的技术社区里,你会频繁看到这样的声音:
"我们用Zustand替代了Redux,删除了好几百行代码" "Redux就像企业级的仪式感,而Zustand让我专注于真正的产品逻辑"
这不是简单的工具更新,而是一场关于工程体验和开发效率的代际差异。本文将从原理层面剖析这个变化背后的深层原因。
Redux本身的设计理念是完美的:单一数据源、可预测的状态流、时间旅行调试。这些特性在当年大型团队的复杂项目中确实发挥了巨大作用。
但是——
Redux要求你遵循一套完整的工作流程:
开发需求
↓
定义 Action Type(常量)
↓
编写 Action Creator(函数)
↓
编写 Reducer(纯函数)
↓
用 combineReducers 整合
↓
用 Provider、useSelector、useDispatch 连接组件
↓
考虑是否需要中间件(middleware)
让我们用一个最简单的例子看看:一个计数器加1。
// 1️⃣ 定义 action type
const INCREMENT = 'INCREMENT';
const DECREMENT = 'DECREMENT';
// 2️⃣ 编写 action creator
function increment() {
return { type: INCREMENT };
}
function decrement() {
return { type: DECREMENT };
}
// 3️⃣ 编写 reducer(必须是纯函数)
function counterReducer(state = 0, action) {
switch(action.type) {
case INCREMENT:
return state + 1;
case DECREMENT:
return state - 1;
default:
return state;
}
}
// 4️⃣ store 配置
import { createStore } from'redux';
const store = createStore(counterReducer);
// 5️⃣ 在组件中使用
import { useSelector, useDispatch } from'react-redux';
function Counter() {
const count = useSelector(state => state);
const dispatch = useDispatch();
return (
<div>
<p>{count}</p>
<button onClick={() => dispatch(increment())}>+1</button>
<button onClick={() => dispatch(decrement())}>-1</button>
</div>
);
}
这是5个文件/5个步骤,只为了实现一个简单的计数器。
而且这还不是最复杂的场景。当你需要:
你会发现自己在写框架代码而不是业务代码。
根据社区的实测反馈,一个中等规模的Redux项目迁移到Zustand:
指标 | 数值 |
|---|---|
平均删除代码行数 | 40%-60% |
Store配置文件数量 | 从5-8个 → 1-2个 |
新开发者上手周期 | 从2-3周 → 2-3天 |
包体积(min+gzip) | 从~12kb → ~2kb |
Zustand是由React Spring和Jotai的作者设计的极简状态管理库。它抛弃了Redux的"仪式感",回归到最本质的状态管理——一个简单的JS对象 + 订阅系统。
import { create } from'zustand';
// 就这么简单
const useCounterStore = create((set) => ({
count: 0,
increment: () =>set((state) => ({ count: state.count + 1 })),
decrement: () =>set((state) => ({ count: state.count - 1 }))
}));
// 在组件中直接用
function Counter() {
const { count, increment, decrement } = useCounterStore();
return (
<div>
<p>{count}</p>
<button onClick={increment}>+1</button>
<button onClick={decrement}>-1</button>
</div>
);
}
就这样。一个文件。核心逻辑3行。
深层的原因在于API设计哲学的差异:
Redux的假设:
Zustand的假设:
这不是技术问题,而是哲学问题。
Redux (redux): 12.3 KB (min+gzip)
Zustand: 1.2 KB (min+gzip)
为什么差10倍?因为Redux需要:
而Zustand只需要:
这是很多人关心的问题。我们来看实际情况:
Redux 的渲染流程:
dispatch(action)
↓
reducer 运算
↓
createSelector 计算新状态
↓
React.memo 判断是否重新渲染
↓
组件重新渲染
中间有多个"关卡",每个关卡都需要开发者手动优化。
Zustand 的渲染流程:
set((state) => ({ ... }))
↓
WeakMap 查询订阅者
↓
订阅该状态的组件 hook 触发更新
↓
组件重新渲染
更直接,更细粒度。Zustand 在 hook 层面就知道谁依赖了什么数据,所以不会有"我改了全局状态,半个应用都重新渲染"的情况。
实战测试(中等规模项目):
场景 | Redux | Zustand |
|---|---|---|
更新单个状态字段 | ~15ms(触发300+组件检查) | ~2ms(只触发订阅组件) |
大列表滚动(1000项) | 需要 memo + selector 优化 | 开箱自动优化 |
用Redux的成本:
用Zustand的成本:
结论:Zustand 节省 70% 的配置成本
这里Redux可能还有优势吗?让我们看一个真实案例:
产品管理系统(用户、权限、表单状态等复杂交互)
Redux 的优点:
但是,Zustand 也能做到这些,只是:
关键问题:是否值得为了这些优点付出 60% 的代码复杂度代价?
大多数团队的答案是:不值得。
只有在这个级别,Redux 的优势才真正体现:
但即使在Meta,也有团队使用 Recoil(Facebook自家的替代品)而不是 Redux。
你正在选择状态管理工具
├─ 项目是否已经用了Redux?
│ ├─ 否 → 优先选择 Zustand
│ │
│ └─ 是 → 继续下一个问题
│
├─ Redux 中是否用到了以下功能?
│ ├─ redux-middleware(thunk/saga)
│ ├─ redux-devtools 的时间旅行功能
│ ├─ 复杂的规范化数据结构(normalizr)
│ │
│ ├─ 以上都有 → 继续用Redux(或升级到 Redux Toolkit)
│ └─ 都没有 → 可以考虑迁移到Zustand
│
└─ 新功能/模块开发
└─ 用Zustand 开发新模块(增量迁移)
Hooks 让状态管理变得更加本地化和组合化。Redux 那一套集中式管理的必要性大大降低了。
从 2015 年到现在,前端工程师对代码清晰度的追求超过了对架构宏大性的追求。
现代开发者倾向于后者。
Redux 当年的一大卖点是 DevTools 调试能力。但现在:
Redux 的垄断优势消失了。
不会。Redux Toolkit 已经让 Redux 的使用体验提升了一个数量级。很多大型项目依然在用,而且运行得很好。
因为选择自由。当一个更轻量、更贴近 React 哲学的工具出现时,很少有理由继续忍受 Redux 的"仪式感"。
团队规模 | 推荐 | 理由 |
|---|---|---|
1-3人 | Zustand | 无需重量级工具 |
4-20人 | Zustand | 开发效率优先 |
20-100人 | Zustand + 团队约定 | 自律的架构 |
100+人 | Redux Toolkit | 工具强制规范 |
真正的智慧不是选择最强大的工具,而是选择最适合当前阶段的工具。
2025年的 React 社区已经做出了选择。下一个问题是:你的团队什么时候开始迁移?