zoukankan      html  css  js  c++  java
  • 通过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
    

      

  • 相关阅读:
    Charles下载和使用
    C# mvc读取模板并修改上传到web
    nginx 安装
    python 测试:wraps
    Linux下MySQL数据库常用基本操作 一
    myeclipse新建maven项目
    java 数据导入xls
    tomcat允许跨域请求:
    Import Projects from git
    c# DataTable 序列化json
  • 原文地址:https://www.cnblogs.com/fuGuy/p/9276142.html
Copyright © 2011-2022 走看看