内容简介:Redux是如何使用的?首先再来回顾一下这个使用demo(谁让这段代码完整地展示了redux的使用)
上集回顾
Redux是如何使用的?首先再来回顾一下这个使用demo(谁让这段代码完整地展示了redux的使用)
如果有小伙伴对这段代码不是很理解的话,建议先去学习Redux的使用再来看这篇源码,这样更加事半功倍。通过上段代码,我们拆分几个比较核心的点,我一一列举一下:
- action的结构是如何的?
- 如何去定义一个reducer?
- combineReducers是如何整合多个reducer的?
- createStore是如何创建一个store?
5.dispatch拿到action到底干了什么?
- subscribe是如何监听状态发生改变的?
- getState是如何拿到所有的状态值的?
上期我们先解决了前三个疑问,这期我们一起来探索后4个问题。
4、createStore是如何创建一个store?
首先我们先撸一个createStore架构出来:
通过这段代码我们知道了传参应该是什么样子和返回了什么。从中我发现了一个问题,createStore接受的是三个参数:1、reducer 2、预加载的state 3、redux-thunk之类的增强器。但是我们平时经常会写成如下这个样子:
我们会在第二个参数就传入了增强器,这跟源代码的参数结构不符哎,但是为什么就可以这么用了。接下来我们就看一下,reducer是如何做这个处理的。
当第二个参数preloadedState的类型是Function的时候,并且第三个参数enhancer未定义的时候,此时preloadedState将会被赋值给enhancer,preloadedState会替代enhancer变成undefined的。有了这么一层转换之后,我们就可以大胆地第二个参数传enhancer了。
解决了这个疑问之后,往下就是解释一下他返回的值是什么东西,这些解答我们就放在下面做解释,这里就不做赘述了。不过在接下去之前,我们得搞清楚下面这组变量代表啥意思。
其中变量isDispatching,作为锁来用,我们redux是一个统一管理状态容器,它要保证数据的一致性,所以同一个时间里,只能做一次数据修改,如果两个action同时触发reducer对同一数据的修改,那么将会带来巨大的灾难。所以变量isDispatching就是为了防止这一点而存在的。
5、dispatch拿到action到底干了啥?
函数dispatch在函数体一开始就进行了三次条件判断,分别是以下三个:
1.判断action是否为简单对象
2.判断action.type是否存在
- 判断当前是否有执行其他的reducer操作
当前三个预置条件判断都成立时,才会执行后续操作,否则抛出异常。在执行reducer的操作的时候用到了try-finally,可能大家平时try-catch用的比较多,这个用到的还是比较少。执行前isDispatching设置为true,阻止后续的action进来触发reducer操作,得到的state值赋值给currentState,完成之后再finally里将isDispatching再改为false,允许后续的action进来触发reducer操作。接着一一通知订阅者做数据更新,不传入任何参数。最后返回当前的action。
6、subscribe是如何监听状态发生改变的?
在注册订阅者之前,做了两个条件判断:
- 判断监听者是否为函数
- 是否有reducer正在进行数据修改(保证数据的一致性)
接下来执行了函数ensureCanMutateNextListeners,下面我们看一下ensureCanMutateNextListeners函数的具体实现逻辑:
逻辑很简单,判断nextListeners和currentListeners是否为同一个引用,还记得初始变量定义那以及函数dispatch内部那两处的代码吗?
这两处将nextListeners和currentListeners引用了同一个数组,而ensureCanMutateNextListeners就是用来判断这种情况的,当nextListeners和currentListeners为同一个引用时,则做一层浅拷贝,这里用的就是Array.prototype.slice方法,该方法会返回一个新的数组,这样就可以达到浅拷贝的效果。
函数ensureCanMutateNextListeners作为处理之后,将新的订阅者加入nextListeners中,并且返回取消订阅的函数unsubscribe。函数unsubscribe执行时,也会执行两个条件判断:
- 是否已经取消订阅(已取消的不必执行)
- 是否有reducer正在进行数据修改(保证数据的一致性)
通过条件判断之后,将该订阅者从nextListeners中删除。看到这里可能有小伙伴们对currentListeners和nextListeners有这么一个疑问?函数dispatch里面将二者引用同一个数组,为啥这里将二者分别引用两个值相同的数组?直接用currentListeners不可以吗?这里这样做其实也是为了数据的一致性,因为有这么一种的情况存在。当redux在通知所有订阅者的时候,此时又有一个新的订阅者加进来了。如果只用currentListeners的话,当新的订阅者插进来的时候,就会打乱原有的顺序,从而引发一些严重的问题。
7、getState是如何拿到所有的状态值的?
getState相比较dispatch要简单许多,返回currentState即可,而这个currentState在每次dispatch得时候都会得到响应的更新。同样是为了保证数据的一致性,当在reducer操作的时候,是不可以读取当前的state值的。
看完是不是已满腔热血
充满了斗志?
以上所述就是小编给大家介绍的《技本功丨知否知否,Redux源码竟如此意味深长(下集)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Ant Colony Optimization
Marco Dorigo、Thomas Stützle / A Bradford Book / 2004-6-4 / USD 45.00
The complex social behaviors of ants have been much studied by science, and computer scientists are now finding that these behavior patterns can provide models for solving difficult combinatorial opti......一起来看看 《Ant Colony Optimization》 这本书的介绍吧!