美文网首页
redux middleware

redux middleware

作者: 落花的季节 | 来源:发表于2017-05-16 17:21 被阅读47次

    middleware

    redux middlewarwe middleware 提供了一个分类处理 action 的机会,在 middleware 中你可以检阅每一个流过的 action,挑选出特定类型的** action 进行相应操作,给你一次改变 action **的机会。

    它提供了位于action被发起之后,reducer到达之前的扩展点。

    为什么需要middleware

    redux数据流

    上图表示的是redux中简单的同步数据流的过程,在view界面触发一个事件后,在后调中dispatch一个action,reducer收到action,更新state并通知view更新。但是如果处理异步action操作 ,这样的方法就不是很好的,单纯的修改 dispatch 或 reducer 的代码显然不具有普世性,我们需要的是可以组合的,自由插拔的插件机制,这一点 redux 借鉴了 koa** 里中间件的思想,koa 是用于构建 web 应用的 NodeJS 框架。另外 reducer 更关心的是数据的转化逻辑,所以 redux 的 middleware 是为了增强 dispatch 而出现的。

    redux的middleware用reduceRight方法,将applyMiddleware
    方法中的参数串起来,原始的dispatch方法会最后执行。

    applyMiddleware的源码及分析
    export default function applyMiddleware(...middlewares) {
      /**
       * 返回值是一个函数,因此在使用的时候是如下形式:
       * var store = applyMiddleware(...midlewares)(createStore)(reducer)
       */
      return (createStore) => (reducer, initialState, enhancer) => {
        // 普通方式创建的store
        var store = createStore(reducer, initialState, enhancer)
        var dispatch = store.dispatch
        var chain = []
    
        /**
         * 将store的一部分接口暴露给中间件
         * 在编写中间件的时候,通常形式为:
         * function middleware(store){
         *     return next => action => { ... }
         * }
         * 参数的store其实就是middlewareAPI
         */
        var middlewareAPI = {
          getState: store.getState,
          /**
           * 这里之所以使用一个匿名函数,而不是`dispatch: dispatch`的形式
           * 是因为在中间件中执行store.dispatch的时候,dispatch的值已经改变
           * 在下面的代码中将会看到dispatch被重新赋值
           */
          dispatch: (action) => dispatch(action)
        }
    
        /**
         * chain是一个数组,数组中的每一项都是一个具有如下形式的函数:
         * function(next){
         *     return function(action){ ... }
         * }
         */
        chain = middlewares.map(middleware => middleware(middlewareAPI))
    
        /**
         * 假设chain为[mw1, mw2, mw3]
         * 那么此时dispatch为mw1(mw2(mw3(store.dispatch)))
         * 即store.dispatch作为mw3的next参数
         * mw3(store.dispatch)作为mw2的next参数,以此类推
         * 最终的返回值是一个函数,其形式为:
         * function(action){ ... }
         * 该函数作为新的dispatch(或者说,包装后的dispatch)
         */
        dispatch = compose(...chain)(store.dispatch)
    
        return {
          ...store,
          dispatch
        }
      }
    }
    

    编写middleware

    如果需要自定义middleware也很简单,这个middleware只接收一个action,执行后也需要返回一个action;如果需要执行下一步,调用next(action)即可。

    基本使用方式:

    store => next => action{
      if(action.type === ''){  //找到对应的action.type的名称执行下面的代码
      
      }else{
         next(action);  //next指向下一个要执行的action
      }
    }
    

    在项目中使用的具体示例:

    //postMessage.js
    export default store => next => action =>{
        if(action.type === "POSTMESSAGE"){
            request.post('/postMessage')
                .send({userName:action.data.user,goodName:action.data.name,description:action.data.description,
                       price:action.data.price,count:action.data.count,telephoneNumber:action.data.telephoneNumber})
                .end((err,res)=>{
                    next({type:"POSTMESSAGE",isSaved:res.body});
                })
        }else{
            next(action);
        }
    }
    //将middleware导出之后,在main函数中调用,通过applyMiddleware将所有的middleware串起来。
    //main.js
    import React from 'react';
    import {render} from "react-dom";
    import {createStore, applyMiddleware} from 'redux';
    import {Provider} from "react-redux";
    import PostMessage from './containers/postMessage';
    
    const createStoreWithMiddleware = applyMiddleware(ResgierMiddleware,LoginMiddleware,NavMiddleware,PostMessageMiddleware)(createStore);
    
    

    相关文章

      网友评论

          本文标题:redux middleware

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