✍️ 模拟 Dan Abramov 思路与设计哲学
🎯 主线:不是为了解决“多组件通信”——而是为了解决状态可控性
🧠 关键词:状态演化、架构异味、不可预测性、调试性、时间旅行
🧨 状态是前端复杂性的第一根导火索
我们不是一开始就要写 Redux 的。 我(Dan Abramov)最早只是遇到一个问题:
在一个中型 React 项目里,我根本不知道哪个组件在什么时候修改了状态。
用 setState 非常方便,但项目开始变得“不可预测”:
- 状态到处都是,每个组件都在维护自己的小世界;
- 多人协作时,彼此
props改一改就全乱; - Bug 不可复现,调试靠猜。
我们不想再靠“命名规范”和“PR 评论”去管状态。我们要架构层面的强约束。
🔀 Flux 是启发,但 Redux 不止是 Flux
当时 Facebook 提出了 Flux 架构,给了我们一个启发:
View → Action → Dispatcher → Store → View
单向数据流,没错,这是关键思想。
但 Flux 有几个问题:
- Dispatcher 是黑盒;
- 没有标准工具链;
- 代码太啰嗦,写一个操作要 5 个文件。
所以我想:有没有一种方式,把 Flux 的数据可控性留下,同时引入函数式编程的纯洁性与组合性?
答案就是 Redux。
🔧 Redux 最初版本只有 99 行
是的,第一版 Redux 源码不到 100 行。我们只做了几件事:
- 把状态放在唯一的
state树中; - 所有修改必须经过
dispatch(action); - 所有变更逻辑写在
reducer(state, action)这个纯函数里。
换句话说:
我们不是设计了一个“状态管理库”,我们设计了一个“状态更新流程调度系统”。
🧬 Redux 核心哲学:可预测性是第一性原理
为什么状态要不可变? 为什么要纯函数? 为什么不让你直接改 state?
不是因为“代码规范”,而是因为这样你才能得到以下能力:
| 能力 | 原理支撑 |
|---|---|
| 时间旅行调试 | 状态快照是不可变的、可还原的 |
| 状态还原与回滚 | 有历史记录链,每次 dispatch 都明确 |
| 审计与回放 | 所有 action 都是结构化事件 |
| 多端同步 | 状态结构可以序列化 + 重构建 |
| 自动化测试 reducer | 函数是纯的,不依赖外部上下文 |
换句话说:
Redux 就是“把状态管理模型,变成了数学建模”。
🧱 我们只保留了 3 条规则
-
单一数据源 整个应用的状态集中存储在一棵对象树中。可以做持久化、调试、快照、同步等一切。
-
状态是只读的 唯一修改方式是
dispatch(action),并通过 reducer 控制行为。 -
变更逻辑必须是纯函数 同样的输入一定得到同样的输出。所有变更路径显性,消除副作用污染。
这三条不是“语法规范”,是我们为状态架构定义的 操作系统级别的权限模型。
🧪 小例子:Redux 的模型其实像数据库日志系统
dispatch({ type: 'INCREMENT' }) // 相当于写入一条操作日志
reducer(state, action) // 相当于执行一条事务
getState() // 相当于查询当前快照
Redux 像一个“前端 mini 数据库”,具备:
- 写入事务日志(action)
- 只读快照(state)
- 流水线 replay(DevTools 回放)
- 插件扩展能力(middleware)
🤝 它为多人协作带来了什么?
在多人协作的项目里,Redux 能解决的痛点是:
- 团队对“数据流动”的认知统一;
- reducer 可以被团队模块维护;
- 中间件实现权限、埋点、打点统一;
- 更容易做自动化测试 + 日志上报。
💬 最常见的问题:Redux 太重?
“你写个按钮还得 dispatch?reducer?action?”
这个问题就像问:“你修一扇门,干嘛要画房屋设计图?”
Redux 从来不是为“按钮计数器”而生,它为的是:
- 多模块协作;
- 多人并行开发;
- 状态的长期维护、升级、调试。
所以我们推出了 redux-toolkit,来简化语法,但不简化哲学。
🔚 总结:Redux 的目标不是方便,而是可控
我们从来不是要让你“少写几行代码”。
我们要让你:
- 明确状态从哪里来,到哪里去;
- 拥有状态调试和回溯的能力;
- 构建一个可以长期维护的应用架构。
如果你只追求“快速出活”,那不一定需要 Redux。 但如果你在构建一个工程化体系下的前端应用平台,Redux 仍然是最纯粹、最透明、最强大的状态管理工具。
⏭️ 下一篇预告
Redux 的哲学我们讲清了,接下来,我们要把这颗“哲学内核”逐行拆开。 在下一篇,我们将进入
createStore(),亲手实现 Redux 的最小状态内核,并解读它的设计精髓。