“Redux 由Dan Abramov设计,最初的目标是创建一个状态管理库,来提供最简化 API,但同时做到行为的完全可预测。当前主流前端框架比如react、vue、flutter等都有使用状态管理,状态管理工具不仅仅只有Redux,但这些工具核心原理都一样,理解Redux 就相当于理解了状态管理工具,本文主要通过编写Redux 伪代码的形式帮助深入理解Redux 。
1.Redux 工作流
Redux 核心在于状态也就是state,所有的 state 都以一个对象树的形式储存在一个单一的 store 中。要想更新 state 中的数据,你需要发起(dispatch)一个 action,action 就是一个普通 JavaScript 对象用来描述发生了什么。每次发起动作时,subscribe中的订阅者会通知所有的订阅者。为了描述 action 如何改变 state 树,你需要编写 reducers。这就是Redux 的工作流,如下图:

2.Redux 伪代码
明白了Redux 工作流,根据工作流编写伪代码就简单了,接下来以实现计数器状态管理为例,编写伪代码。在编写之前牢记Redux工作流,再把Redux 工作流中的各种概念忘掉,一旦记住这些概念,思路会被困住,我们从零开始一步步实现它,这些概念该出现的时候会出现,只有这样才会理解为什么要这么设计。
第一步实现极简状态管理,代码如下:
let state = {
count: 0
}
没错,上面就是一个状态管理工具,但这么做有两个问题,第一状态被修改之后其他用的地方不知道已经修改。第二count名字太固定了不能通用。
第二步我们尝试来解决第一步引起的问题,首先对状态封装,实现通用状态管理器;其次增加管理订阅者功能,管理状态更改后通知谁,最后要有通知订阅者功能,当状态更新后通知相关订阅者。
const createStore = function (initState) {
let state = initState;
let listeners = [];
/*订阅管理*/
function subscribe(listener) {
listeners.push(listener);
}
/*更新状态*/
function dispatch(newState) {
state = newState;
/*通知*/
for (let i = 0; i < listeners.length; i++) {
const listener = listeners[i];
listener();
}
}
/*获取状态*/
function getState() {
return state;
}
return {
subscribe,
dispatch,
getState
}
}
到这里,熟悉Redux源码的可能已经看出来了,这基本就是一个精简版Redux了,它的功能很简单,获取状态、管理订阅、更新状态并通知订阅者。但这样做还有一个问题,比如我定义计数器状态,理应是数字,但传值的时候我给状态传"hello world",这不就背离初衷了吗?
第三步解决第二步的那个随便传值的问题,首先定制一个状态的操作清单,超出的我们不操作;其次对这个清单上的每个操作制定一个计划书,每个操作都按照计划书上的做。这样保证操作动作是可控的,操作也是可控的。
我们把清单上的操作叫做action,把操作计划书叫做reducer,对,就是工作流中的那俩名字,反过来action和reducer对应的含义也就是本例中操作和操作计划书,是不是它俩的含义就豁然开朗了?
function dispatch(action) {
state = reducer(state, action);
/*通知*/
for (let i = 0; i < listeners.length; i++) {
const listener = listeners[i];
listener();
}
}
到这里,一个功能相对完善的Redux就完成了,核心功能都已经具备,当然也有很多不足的地方,比如管理订阅者功能不能退订,比如大型项目开发,会有很多状态,这必然会有很多计划书,所有的计划书写在一个 reducer 函数里面,会导致 reducer 函数及其庞大复杂,这就需提供功能把多个 reducer 合并成一个 reducer。本文主要帮助理解Redux,这个就不再讨论了。
3.Redux 重要性
Redux作为状态管理工具,它对状态的每一步更新都做到可预测,使得数据管理和视图更新更简便,这对于当前流行的数据视图分离的开发模式有重要作用。当然State 是只读的,这个是Redux 三大核心原则,这里的更新只是表达想要修改的意图。
状态管理工具不只Redux一个,Dan在与字节跳动的访谈互动中被问到对 React 状态管理工具的看法,Dan表示”不会去推荐任何一个特定的库。真正重要的问题不是选择什么状态管理库,而是理解「状态」的类型,理解「状态」是什么。因为「状态」是一个比较笼统的、比较大的概念,我认为我们不应该去浮于表面地去讨论哪个库更好,而是去看你要处理的状态是什么种类,使用这些库的目的是什么,选用不同方案带来的差异是什么”。这句话很值得回味,最重要的是理解状态和使用目的,工具都是可选的嘛。
4. 结语
Redux 仅仅是个工具,开发中有一堆理由去使用它,也有很多的理由不去使用它,但不妨碍它是一个伟大工具,正如Dan所说,真正重要的是理解,只有理解了它的理念和原理,用不用或者用谁都不重要。
- END -





