• 技术文章 >web前端 >js教程

    通过ES6写法去对Redux部分源码解读

    不言不言2018-07-07 11:12:51原创731
    这篇文章主要介绍了关于通过ES6写法去对Redux部分源码解读,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下

    在Redux源码中主要有四个文件createStore,applyMiddleware,bindActionCreators,combineRedures

    createStore.js

    export default function createStore(reducer, preloadedState, enhancer),其中reducer函数是用来计算规则,preloadedState是初始状态,enhancer(高阶组合函数)是用来增强store对象,返回增强后的store

    createStore将通过闭包的方式,封装私有变量,该store中的state等状态会被保存

    //返回 store 暴漏出的接口

    return {
    dispatch, //唯一一个可以改变 state 的哈按时
    subscribe, //订阅一个状态改变后,要触发的监听函数
    getState, // 获取 store 里的 state
    replaceReducer, //Redux热加载的时候可以替换 Reducer
    [$$observable]: observable //对象的私有属性,供内部使用
    }

    如果preloadedState 是function,而enhancer为null,那么将两者交换,enhancer必须是function

    if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {
    enhancer = preloadedState // 把 preloadedState 赋值给 enhancer
    preloadedState = undefined // 把 preloadedState 赋值为 undefined
    }

    function subscribe(listener)主要通过观察者模式返回一个取消订阅的函数,订阅通过一个数组队列来完成,添加或者取消监听之前都会保存一份订阅快照

    在function dispatch(action)中,

    //标记 dispatch 正在运行

    isDispatching = true

    //执行当前 Reducer 函数返回新的 state

    currentState = currentReducer(currentState, action)

    然后对所有的订阅数组队列,进行遍历

    //所有的的监听函数赋值给 listeners
    var listeners = currentListeners = nextListeners
     
    //遍历所有的监听函数
    for (var i = 0; i < listeners.length; i++) {
     
    // 执行每一个监听函数
    listeners[i]()

    applyMiddleware

    return一个函数,它可以接受createStore方法作为参数,给返回的store的dispatch方法再进行一次包装

    return function (reducer, preloadedState, enhancer) {
    var store = createStore(reducer, preloadedState, enhancer);
    var _dispatch = store.dispatch; //获取dispatch
    var 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 可以直接 dispath
    return bindActionCreator(actionCreators, dispatch);
    }
    如果是Object对象的话,遍历Object的key,获取Oobject每个key对应的value
    // 获取 actionCreators 所有的 key
    var keys = Object.keys(actionCreators);
    // 用来保存新 转换后的 actionCreators
    var boundActionCreators = {};
     
    // 遍历 所有的 actionCreators keys
    for (var i = 0; i < keys.length; i++) {
    var key = keys[i];
    // 获取当前的 actionCreator
    var actionCreator = actionCreators[key];
    // 当前的 actionCreator 是一个函数
    if (typeof actionCreator === 'function') {
    // 调用 bindActionCreator , 返回包装后的 actionCreators , 包装后 actionCreators 可以直接 dispath
    boundActionCreators[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++) {
    //获取当前的 key
    var key = finalReducerKeys[i]
    //获取当前 reducer
    var reducer = finalReducers[key]
    //获取当前 key 的 state
    var previousStateForKey = state[key]
    //执行 reducer ,获取 state
    var nextStateForKey = reducer(previousStateForKey, action)
    //判断执行完Reducer后, 返回回来的 nextStateForKey 是 undefined
    if (typeof nextStateForKey === 'undefined') {
    //得到 Undefined 状态的错误消息
    var errorMessage = getUndefinedStateErrorMessage(key, action)
    //抛出异常
    throw new Error(errorMessage)
    }
    //赋值给 nextState
    nextState[key] = nextStateForKey
    //判断 state 是否经过 Reducer 改变了
    hasChanged = hasChanged || nextStateForKey !== previousStateForKey
    }
    //返回state
    return hasChanged ? nextState : state

    以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

    相关推荐:

    Javascript中的this对象

    foreach, for in, for of 之间的异同

    React-Reflux的基础介绍

    以上就是通过ES6写法去对Redux部分源码解读的详细内容,更多请关注php中文网其它相关文章!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:ES6
    上一篇:Javascript中的this对象 下一篇:JS浏览器事件循环机制
    VIP课程(WEB全栈开发)

    相关文章推荐

    • 【活动】充值PHP中文网VIP即送云服务器• JavaScript怎么通过querySelectorAll()方法查找html元素• 整理JavaScript中cookie操作对象的应用• 完全掌握DOM属性成员与文档流• javaScript归纳总结之Dom获取集合元素对象• 深入浅析window.location对象实现页面跳转
    1/1

    PHP中文网