Redux 源码分析

原创 amandakelake 教程 框架与工具 140阅读 2018-03-16 09:10:36 举报

我在学习过程中喜欢做记录,分享的是自己在前端之路上的一些积累和思考,希望能跟大家一起交流与进步。 这是我的github博客,欢迎star

一、compose

这是一个高阶函数,返回函数的函数被称为高阶函数
它的作用是通过传入函数引用的方式,从右到左依次调用函数,并把上一个函数的值作为下一个函数的参数
文档里面的注释写的很清楚

再看被编译成ES5的写法,其中b.apply(underfined, arguments)是因为b()这里代表的是全局,所以要绑定underfined

二、bindActionCreators

主要实现的就是将ActionCreatordispatch进行绑定,官方的注释里面这么写的

Turns an object whose values are action creators, into an object with the same keys, but with every action creator wrapped into a dispatch call so they may be invoked directly.

翻译过来就是bindActionCreators将值为actionCreator的对象转化成具有相同键值的对象,但是每一个actionCreator都会被dispatch所包裹调用,因此可以直接使用

先看bindActionCreator,看清楚了,没有s的

返回一个新的函数,该函数调用时会将actionCreator返回的纯对象进行dispatch

接下来看bindActionCreators
代码的作用是对对象actionCreators中的所有值调用bindActionCreator,然后返回新的对象

三、combineReducers

官方文档

combineReducers 辅助函数的作用是,把一个由多个不同 reducer 函数作为 value 的 object,合并成一个最终的 reducer 函数,然后就可以对这个 reducer 调用 createStore

combineReducers函数总的来说是比较简单的,将大的reducer函数拆分成一个个小的reducer分别处理,

先看代码

使用变量nextState记录本次执行reducer返回的state
hasChanged用来记录前后state是否发生改变。
循环遍历reducers,将对应的store的部分交给相关的reducer处理,当然对应各个reducer返回的新的state仍然不可以是undefined
最后根据hasChanged是否改变来决定返回nextState还是state,这样就保证了在不变的情况下仍然返回的是同一个对象。

总结来说就是接收一个对象reducers,将参数过滤后返回一个函数。该函数里有一个过滤参数后的对象 finalReducers,遍历该对象,然后执行对象中的每一个 reducer 函数,最后将新的 state 返回。

再看一个使用到的辅助函数assertReducerShape

1、判断reducers中的每一个reduceraction{ type: ActionTypes.INIT }时是否有初始值,如果没有则会抛出异常。
2、对reduer执行一次随机的action,如果没有返回,则抛出错误,告知你不要处理redux中的私有的action,对于未知的action应当返回当前的state。并且初始值不能为undefined,但是可以是null

四、createStore

官方文档

创建一个 Redux store 来以存放应用中所有的 state。
应用中应有且仅有一个 store。

有三个参数,reducer是处理后的reducer纯函数,preloadedState是初始状态,而enhancer使用相对较少,enhancer是一个高阶函数,用来对原始的createStore的功能进行增强。

先看它的核心代码

接下来再看看它里面封装的几个方法

1、dispatch

2、subscribe

subscribe用来订阅store的变化

为什么会存在nextListeners呢?
 
首先可以在任何时间点添加listener。无论是dispatch action时,还是state值正在发生改变的时候。但是需要注意的,在每一次调用dispatch之前,订阅者仅仅只是一份快照(snapshot),如果是在listeners被调用期间发生订阅(subscribe)或者解除订阅(unsubscribe),在本次通知中并不会立即生效,而是在下次中生效。因此添加的过程是在nextListeners中添加的订阅者,而不是直接添加到currentListeners,然后在每一次调用dispatch的时候都会做下面的赋值行为来同步currentListenersnextListeners

3、getState

这个……emm👶

4、replaceReducer

热更新reducer用的,用的比较少

五、applyMiddleware

看它的代码之前,先加一点预备知识:柯里化函数,通常也称部分求值

在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。

举个例子

还不知道的同学可以先去稍微补一下,大概知道柯里化函数干嘛的就行了

由于采用了ES6的结构赋值和箭头函数,applyMiddleware代码很短

评论 ( 1 )
最新评论
大神M 2018-03-16 10:03:33 1F

Get,做个标记,一会儿再看!