这篇文章主要介绍了关于通过es6写法去对redux部分源码解读,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下
在redux源码中主要有四个文件createstore,applymiddleware,bindactioncreators,combineredures
createstore.jsexport default function createstore(reducer, preloadedstate, enhancer),其中reducer函数是用来计算规则,preloadedstate是初始状态,enhancer(高阶组合函数)是用来增强store对象,返回增强后的store
createstore将通过闭包的方式,封装私有变量,该store中的state等状态会被保存
//返回 store 暴漏出的接口
return {dispatch, //唯一一个可以改变 state 的哈按时subscribe, //订阅一个状态改变后,要触发的监听函数getstate, // 获取 store 里的 statereplacereducer, //redux热加载的时候可以替换 reducer[$$observable]: observable //对象的私有属性,供内部使用}
如果preloadedstate 是function,而enhancer为null,那么将两者交换,enhancer必须是function
if (typeof preloadedstate === 'function' && typeof enhancer === 'undefined') {enhancer = preloadedstate // 把 preloadedstate 赋值给 enhancerpreloadedstate = undefined // 把 preloadedstate 赋值为 undefined}
function subscribe(listener)主要通过观察者模式返回一个取消订阅的函数,订阅通过一个数组队列来完成,添加或者取消监听之前都会保存一份订阅快照
在function dispatch(action)中,
//标记 dispatch 正在运行
isdispatching = true
//执行当前 reducer 函数返回新的 state
currentstate = currentreducer(currentstate, action)
然后对所有的订阅数组队列,进行遍历
//所有的的监听函数赋值给 listenersvar listeners = currentlisteners = nextlisteners //遍历所有的监听函数for (var i = 0; i < listeners.length; i++) { // 执行每一个监听函数listeners[i]()
applymiddlewarereturn一个函数,它可以接受createstore方法作为参数,给返回的store的dispatch方法再进行一次包装
return function (reducer, preloadedstate, enhancer) {var store = createstore(reducer, preloadedstate, enhancer);var _dispatch = store.dispatch; //获取dispatchvar chain = []; var middlewareapi = {getstate: store.getstate,dispatch: function dispatch(action) {return _dispatch(action);}};chain = middlewares.map(function (middleware) { //遍历middlewares绑定return middleware(middlewareapi);});_dispatch = compose.apply(undefined, chain)(store.dispatch); return _extends({}, store, {dispatch: _dispatch});};
bindactioncreators将action和dispatch绑定起来:
bindactioncreators(actioncreators, dispatch)
// 判断 actioncreators 是一个函数if (typeof actioncreators === 'function') {// 调用 bindactioncreator , 返回包装后的 actioncreators , 包装后 actioncreators 可以直接 dispathreturn bindactioncreator(actioncreators, dispatch);}如果是object对象的话,遍历object的key,获取oobject每个key对应的value// 获取 actioncreators 所有的 keyvar keys = object.keys(actioncreators);// 用来保存新 转换后的 actioncreatorsvar boundactioncreators = {}; // 遍历 所有的 actioncreators keysfor (var i = 0; i < keys.length; i++) {var key = keys[i];// 获取当前的 actioncreatorvar actioncreator = actioncreators[key];// 当前的 actioncreator 是一个函数if (typeof actioncreator === 'function') {// 调用 bindactioncreator , 返回包装后的 actioncreators , 包装后 actioncreators 可以直接 dispathboundactioncreators[key] = bindactioncreator(actioncreator, dispatch);}
combinereducers获取combinereduces传进来的对象,获取对象的所有key集合finalreducerkeys。
<provider store={store}></provider>
获取state集合,遍历reducers集合找到当前reducers中的state,然后和经过reducer后的获取的新的state做对比,如果发生改变返回state
//循环遍历 finalreducerkeys ,执行所有的 reducer, 所以大家一定不要有相同的 action.type ,否则你的状态一定会混乱的for (var i = 0; i < finalreducerkeys.length; i++) {//获取当前的 keyvar key = finalreducerkeys[i]//获取当前 reducervar reducer = finalreducers[key]//获取当前 key 的 statevar previousstateforkey = state[key]//执行 reducer ,获取 statevar nextstateforkey = reducer(previousstateforkey, action)//判断执行完reducer后, 返回回来的 nextstateforkey 是 undefinedif (typeof nextstateforkey === 'undefined') {//得到 undefined 状态的错误消息var errormessage = getundefinedstateerrormessage(key, action)//抛出异常throw new error(errormessage)}//赋值给 nextstatenextstate[key] = nextstateforkey//判断 state 是否经过 reducer 改变了haschanged = haschanged || nextstateforkey !== previousstateforkey}//返回statereturn haschanged ? nextstate : state
以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注!
相关推荐:
javascript中的this对象
foreach, for in, for of 之间的异同
react-reflux的基础介绍
以上就是通过es6写法去对redux部分源码解读的详细内容。