美文网首页
redux中间件详解

redux中间件详解

作者: fanstastic | 来源:发表于2019-01-28 17:29 被阅读0次
    • 回顾redux

      • redux解决了什么问题
      • redux基本架构图
      • dispatch函数
    • 如何编写中间件

      • 中间件函数基本格式
      • 中间件洋葱模型
    • redux中间件源码解析

      • applyMiddleware函数
      • compose函数

    1. 回顾redux

    • redux解决了什么问题

      • 一个react应用就是一颗组件树,react是单向数据流。单向数据流的情况下,组件之间数据如何通信?组件的公共数据应该放在哪里?


        redux.png
    • redux基本架构图

    0_cntBtPADjE2ykLSP.png
    • dispatch函数

    redux-diagram.jpg

    2. 如何编写redux中间件

    • 中间件函数本质就是对dispatch方法的扩展,那么如何优雅的扩展dispatch方法?
    • mid1,mid2,mid3分别为三个中间件函数,编写中间件函数有一个固定格式,必须按照以下格式编写
    // getState获取当前state的状态
    function mid1({ getState }) {
    // next指向下一个要执行的(action) => {}匿名函数
      return (next) => {
      // action是指dispatch中的对象
        return (action) => {
          console.log('start mid1')
          next(action)
          console.log('end mid1');
        }
      }
    }
    // getState获取当前state的状态
    function mid2({ getState }) {
    // next指向下一个要执行的(action) => {}匿名函数
      return (next) => {
      // action是指dispatch中的对象
        return (action) => {
          console.log('start mid2')
          next(action)
          console.log('end mid2');
        }
      }
    }
    // getState获取当前state的状态
    function mid3({ getState }) {
    // next指向下一个要执行的(action) => {}匿名函数
      return (next) => {
        // action是指dispatch中的对象
        return (action) => {
          console.log('start mid3')
          next(action)
          console.log('getState() :', getState());
          console.log('end mid3');
        }
      }
    }
    // 配置中间件
    const middleware = [mid1, mid2, mid3]
    // 创建store
    const finalCreateStore = applyMiddleware(...middleware)(createStore)
    
    • 触发一次dispatch后的执行结果


      WechatIMG95log.jpeg
    • 中间件洋葱模型

    • 当用户调用dispatch时,首先执行mid1中间件,在mid1中调用next执行mid2中间件,依次执行,最终调用dispatch,dispatch调用结束后,依次执行剩余中间件代码。


      zIjmUzn.png

    3. redux中间件源码解析

    // 配置中间件
    const middleware = [mid1, mid2, mid3]
    // 创建store
    const finalCreateStore = applyMiddleware(...middleware)(createStore)
    
    • applyMiddleware函数

    function applyMiddleware(...middlewares) {
    // createStore创建store调用的方法
    return createStore => (...args) => {
      const store = createStore(...args)
      const chain = middlewares.map(middleware => middleware())
      /*
        chain: [
          f1: (next) => (action) => { console.log('start mid1'); next(action); console.log('end mid1'); },
          f2: (next) => (action) => { console.log('start mid2'); next(action); console.log('end mid2'); },
          f3: (next) => (action) => { console.log('start mid3'); next(action); console.log('end mid3'); }
        ]
      */
      dispatch = compose(...chain)(store.dispatch)
      /*
        dispatch = f1(f2(f3(store.dispatch)))
      */
      return {
        ...store,
        dispatch
      }
    }
    }
    
    • compose

    //  (f1, f2, f3) -> (...args) => f1(f2(f3(...args)))
    function compose(...funcs) {
      if (funcs.length === 0) {
        return arg => arg
      }
    
      if (funcs.length === 1) {
        return funcs[0]
      }
    
      return funcs.reduce((a, b) => (...args) => a(b(...args)))
    }
    
    

    相关文章

      网友评论

          本文标题:redux中间件详解

          本文链接:https://www.haomeiwen.com/subject/rgtzjqtx.html