🔄 Redux
一句话定性
2015 年,Dan Abramov 受 Flux 和 Elm 启发,做出 Redux:单一数据源 + 纯函数 reducer + 不可变更新,把状态变化变成一条可追溯、可重放、可时间旅行的事件流。它用极致的可预测性定义了一个时代,也用令人发指的样板代码逼出了它的所有反叛者。
一、它是什么 & 出现的时代
Redux 是一个可预测的状态容器,2015 年由 Dan Abramov(后加入 React 团队)和 Andrew Clark 创建,诞生于 2013-2018 SPA时代的 React 生态。
它的直接前身是 Facebook 2014 年提出的 Flux 架构(一种”数据只能单向流动”的思想),Redux 把 Flux 简化、并融入了 Elm 架构(函数式、不可变)的精髓。
一个著名的演示
Dan Abramov 在 React Europe 2015 上演示 Redux 的时间旅行调试(time-travel debugging)——把状态变化录下来、来回拖动重放——惊艳全场,Redux 一夜成名。
二、为什么会出现(解决上一代什么痛点)
Flux 之前的混乱
2013-2018 SPA时代的组件化带来跨组件状态共享难题(见 状态管理演进史)。早期的 MVC / 双向绑定下,数据流向是双向甚至网状的:模型改视图、视图改模型,改着改着就成了”谁也说不清现在的状态为什么是这样”。
Facebook 自己就被这个坑惨了(著名的”未读消息数对不上”bug)。Flux 给出的药方是:强制数据单向流动。Redux 进一步把它收敛到三条铁律。
三、核心机制 & 为什么流行
三大原则(Redux 的宪法)
- 单一数据源(Single Source of Truth):整个应用的状态存在一棵 state 树里,只有一个 store。
- 状态只读:不能直接改 state,唯一改变方式是 dispatch 一个 action(描述”发生了什么”的纯对象)。
- 用纯函数(reducer)做变更:
(oldState, action) => newState,纯函数 + 不可变,相同输入永远得到相同输出。
单向数据流
┌──────────────────────────────────────────────┐
│ │
▼ │
View ──dispatch(action)──► Store ──► Reducer ──► new State
▲ │
└───────────── 订阅,state 变就重渲染 ─────────────┘
数据只朝一个方向转圈,永远不会”反向偷偷改”。
为什么流行
可预测性是它的全部魅力
- 可追溯:每次变化都是一个有名字的 action,像一本”状态变更日志”。
- 时间旅行调试:能录制 action 序列、回退、重放——debug 体验降维打击。
- 可测试:reducer 是纯函数,测试不需要 mock 任何东西。
- 生态强大:Redux DevTools、中间件(redux-thunk / redux-saga 处理异步)、与 React 的 react-redux 绑定。
四、带来的新问题 / 副作用
"为了改一个值,要写三个文件"
- 样板代码(boilerplate)爆炸:加一个功能要写 action type 常量、action creator、reducer case、再 dispatch、再 connect——改一个值的链路又长又啰嗦,这是 Redux 被诟病最多的一点。
- 不可变更新繁琐:手写
{...state, nested: {...state.nested, x: 1}}这种深层展开,易错又难读。- 异步是个痛点:reducer 必须纯,异步逻辑只能塞进中间件(thunk/saga),又是一层学习成本。
- 过度使用:很多小项目根本不需要全局 store,却跟风上 Redux,徒增复杂度(违背奥卡姆剃刀)。
五、现状 / 演化:Redux Toolkit 的救赎
RTK——Redux 官方的自我修正
面对”样板太多”的群嘲,Redux 团队推出 Redux Toolkit(RTK),成为官方推荐的标准写法:
createSlice一次性生成 action + reducer,样板砍掉一大半。- 内置 Immer,可以”看似直接修改”state(
state.x = 1),底层自动转成不可变更新——消灭了手写展开运算符的痛苦。createAsyncThunk、RTK Query(数据请求与缓存)把异步也收编了。
如今:大型、复杂、多人协作的企业级应用里,Redux(+ RTK)仍是最稳妥的选择——它的”啰嗦”在大团队里反而变成”清晰的约束”。但中小项目越来越多地转向 Zustand 等轻量方案。
六、对后续技术的影响(因果链)
Flux(2014 单向数据流思想) + Elm(函数式/不可变)
│
▼
Redux(2015, Dan Abramov)── 强绑定 [[React]]
│
┌───────────────────┼───────────────────────────┐
▼ ▼ ▼
单一数据源 纯 reducer + 不可变 时间旅行调试
│ │ │
▼ ▼ ▼
可预测但样板多 ──┬──► [[MobX]] 反样板(响应式/可变)
│
├──► [[Zustand]] 反叛(无 Provider/极简)
│
├──► [[Vuex-Pinia\|Vuex]] 借鉴单向思想到 [[Vue]] 生态
│
└──► Redux Toolkit 自救(createSlice + Immer,砍样板)
历史地位
Redux 是状态管理史的奠基者和参照系:它确立了”单一数据源 + 单向数据流 + 不可变”这套至今仍是教科书级别的可预测性范式。它后来所有的”竞争对手”,本质上都是在回答同一个问题——“如何在不丢掉可预测性的前提下,把 Redux 的样板砍掉?” 它定义了整只 钟摆的一端。
🔗 相关:状态管理演进史 | MobX | Vuex-Pinia | Zustand | React | 2013-2018 SPA时代