Redux源码阅读笔记(1) - Why Redux?

Posted by Lxxyx on 2017-05-20

cover

起因

日常的习惯里,就有阅读开源项目源代码的习惯。
之前的项目中则大量的应用了Redux作为状态容器,也积累了一些问题,所以今天试着阅读Redux源代码,去解决自己的困惑。

在网络上Why ReduxRedux原理分析Redux源代码分析之类的文章层出不穷,之所以写这篇文章的原因是为了解决自己在使用Redux时说产生的一些好奇与困惑。并非科普文,如果你有遇到类似的问题,不妨看看~

问题

一直认为,带着问题去阅读源代码,比漫无边际的阅读要有效的多。就像自己很喜欢的那句话一样:

“师必有名。” – 《礼记·檀弓下》

下面则是自己在使用Redux时遇到的一些问题。

  • 为什么要用Redux,解决了什么问题?
  • Redux的原理,如何与各类框架去做一个适配
  • 为什么每次都要返回全新的State?而不能直接在原来的State做修改?
  • Redux中间件相关的问题,Redux-saga,Redux-thunk等经典中间件是怎么实现的

阅读的Redux版本是Github拉取的最新版,commit号是:27ab1697d82175e00f34508b3e76d2f17ed894bd

初见

Redux的源代码,严密,简洁且有力,而且注释超级多,所以读起来还是很舒服的。
当然在解释源代码之前,需要先解决第一个问题:Why Redux?

1. Why Redux?

对于Why Redux?这个问题,很多人都有自己的理解。
对于我而言,这个问题的答案是如下两点:

  1. 前端应用的复杂化,需要一个可靠的状态管理器来管理前端状态
  2. React/Vue等MVVM框架的兴起,状态决定视图,组件之间数据共享,跨级交流的困难

这两点互相作用互相影响,我们需要一个可靠的全局状态管理器,管理全局和共享状态,解决组件数据共享,跨级交流困难的问题。

状态的复杂化

至于前端状态的复杂化,在Redux官方的文档中,有这么一段话:

随着 JavaScript 单页应用开发日趋复杂,JavaScript 需要管理比任何时候都要多的 state (状态),管理不断变化的 state 非常困难。如果一个 model 的变化会引起另一个 model 变化,那么当 view 变化时,就可能引起对应 model 以及另一个 model 的变化,依次地,可能会引起另一个 view 的变化。直至你搞不清楚到底发生了什么。state 在什么时候,由于什么原因,如何变化已然不受控制。 当系统变得错综复杂的时候,想重现问题或者添加新功能就会变得举步维艰。

具体有多复杂,每个人的业务场景都不一样,这里就不赘述了。

React/Vue等MVVM框架的兴起

React/Vue等MVVM框架发展这么久了,早已为大部分前端工程师所熟知。而Redux/Flux/Vuex/Mobx等全局状态管理器,则是配合React/Vue等MVVM框架来完成大中型应用的开发。

这儿的标题是React/Vue等MVVM框架的兴起,也就是我认为Why Redux这个问题的答案之一就是这个。

世间万物都是有联系的,对重型Web Application开发/更简便的前端开发的需要促进了各类前端框架的出现,而各类前端框架自己也存在一些痛点,如React中组件层级嵌套过深,组件交互麻烦等问题则推进了Redux这类状态管理容器的出现。

如果前端每天的需求只是做一些简单的展示页,那么React/Vue这类框架很有可能只是昙花一现或是束之高阁,因为没有实际的需求。此时引进Vue/React的成本是大于收益的。


React/Vue等MVVM框架的核心特点,那就是状态决定视图,翻译成伪代码就是:

1
f(state) => view

使用React/Vue时候,在数据管理方面是有痛点的。React为View层,本身不具有好的数据管理方式,而Vue则相似,均需要配合Redux/Vuex来实现数据管理。

具体的痛点,在这儿,Vue的官方文档给了详尽的解释:

一个状态自管理应用包含以下几个部分

  • state,驱动应用的数据源;
  • view,以声明方式将state映射到视图;
  • actions,响应在view上的用户输入导致的状态变化。

以下是一个表示“单向数据流”理念的极简示意:

但是,当我们的应用遇到多个组件共享状态时,单向数据流的简洁性很容易被破坏:

  • 多个视图依赖于同一状态。
  • 来自不同视图的行为需要变更同一状态。

对于问题一,传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。对于问题二,我们经常会采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱,通常会导致无法维护的代码。

来源:Vuex 是什么?

而Redux,就是为了解决上述问题而来。