• 5、redux源码解析


    在开发时,也许需要更多地包装dispatch以实现更加完善的功能。
    比如包装 dispatch来打印日志,包装dispatch以支持Promise,各种包装需要密切配合。

    之前两篇代码的汇总:

    //包装dispatch来打印日志
    const addLoggingToDispatch = (store) => {
      const rawDispatch = store.dispatch;
      if(!console.group){
        return rawDispatch;
      }
      return (action) => {
        console.group(action.type);
        console.log('%c previous state', 'color: gray', store.getState());
        console.log('%c action', 'color: blue', action);
        const returnValue = rawDispatch(action);
        console.log('%c previous state', 'color: gray', store.getState());
        console.log.group(action.type);
        return returnValue
      }
    }
    //dispatch支持传入promise对象
    const addPromiseSupportToDispatch = (store) => {
      const rawDispatch = store.dispatch;
      return (action) => {
        if(typeof action.then === 'function'){
          return action.then(rawDispatch);
        }
        return rawDispatch(action);
      }
    }

    为了使这两种方式同时运作,可以写一个用来初始化sotre的函数,以丰富store.dispatch的功能。

    const configureStore = () => {
      const store = createStore(App);
      if(process.env.NODE_ENV !== 'production'){
        store.dispatch = addLoggingToDispatch(store);
      }
      store.dispatch = addPromiseSupportToDispatch(store);
      return store;
    }

    这样便返回了一个包含有增强型dispatch的store,
    仔细研究configureStore函数,我们发现addPromiseSupportToDispatch方法返回了一个符合正常用法的dispatch,
    此时它支持dispatch参数是一个promise,它会等待Promise resolve后,利用rawDispatch再次进行action派发。
    那么这个rawDispatch是最初、最原始的dispatch吗?在开发环境下,显然不是。因为执行sotre.dispatch = addPromiseSupportToDispatch(store)之前,
    已经执行了store.dispatch = addLoggingToDispatch(store)。
    换名话说,在执行addPromiseSupportToDispatch时,store.dispatch是上一个包装版本的sotre.dispatch。
    明白了这层关系,我们就会想到rawDispatch这个全名不十分准确,它本意是最原始的store.dispatch , 但是在代码执行
    时,每一个中间件所获得的store.dispatch都已经被改造,我们将其命名为next。
    前面的例子改造之后:

    const addLoggingToDispatch = (store) => {
      const next = store.dispatch;
      if(!console.group){
        return next
      }
      return (action) => {
        //...
        const resultValue = next(action);
        //...
        return resultValue;
      }
    }
    const addPromiseSupportToDispatch = (store) => {
      const next = store.dispatch;
      return (action) => {
        if(typeof action.then === 'function'){
          return action.then(next)
        }
        return next(action);
      }
    }

    为了避免上面这样零散地修改公共的api接口,我们可以将这种包装过程收敛 - 声明一个数组,即中间件数组。
    它的每一项都是一个中间件,然后统一根据中间件来增强dispatch。

    const configureStore = () => {
      const store = createStore(App);
      const middleWare = [];
    
      if(process.env.NODE_ENV !== 'production'){
        middleWare.push(addLoggingToDispatch);
      }
      middleWare.push(addPromiseSupportToDispatch);
      wrapDispatchWithMiddlewares(store, middlewares);
      return store;
      
    }
     以上代码中,并不直接执行addLoggingToDispatch和addPromiseToDispatch,而
     是将其push到middlewares数组,然后统一执行。这里说的统一执行就是指代码中的wrapDispatchWithMiddleWares(store, middlewares);
    
    
     const wrapDispatchWithMiddlewares = (store, middlewares) => {
      middlewares.forEach(middleware => {
        store.dispatch = middleware(store)(store.dispatch);
      })
     }
  • 相关阅读:
    xcode 常用插件 加快开发速度 --严焕培
    iOS,蓝牙开发!!--By帮雷
    获取加速度数据,陀螺仪数据,磁场数据的两种方式-陈鹏
    简单仿京东"筛选"界面 双导航栏控制器共存 by Nicky.Tsui
    扩展NSDate类实现快捷使用 —— 昉
    如何实现视图圆角效果的三种方法及比较——董鑫
    无意进去UIView随笔闹腾着玩 -by 胡 xu
    简单实现UITableView索引功能(中英文首字母索引)(一) ByH罗
    动画推荐-By胡罗
    [手游项目3]-20-golang向上取整、向下取整和四舍五入
  • 原文地址:https://www.cnblogs.com/hellolol/p/11379340.html
Copyright © 2020-2023  润新知