眼花缭乱的redux中间件,也不过如此

4 篇文章 0 订阅
3 篇文章 0 订阅

在平时的react项目开发中,我们除了会用到redux的基本功能外,还要借助redux的一些中间件(middleware)去完成一些高级的操作,例如使用redux-logger中间件去打印日志,使用redux-thunk去派发一个方法,使用redux-promise去派发一个promise等等。

下面,就让我们一起来看看这几个插件的基本使用,以及实现吧。

首选,我们需要知道redux中间件的一个基本格式,即每一个中间件的基本格式都是如下这样:

 function loggerMiddleware({ getState, dispatch }) {
  return function (next) {
    return function (action) {
    };
  };
}

注意:中间件内部会有两次返回操作,最外层接收getState,dispatch(store中的dispatch) 参数,其次中间那一层接收 一个next方法(重写的dispatch方法)作为参数,最后一层函数接收本次派发的action对象,有了这个基本的框架认识,那么写出下面几个中间件便不再是难事了。

redux-logger

//getState用来获取仓库状态 dispatch用来重新派发动作
//每一个中间件都会接受到getState,dispatch这两个参数
export default function loggerMiddleware({ getState, dispatch }) {
  return function (next) {
    //next是为了调用原生的dispatch方法
    return function (action) {
      //打印派发之前的状态
      console.log(`老状态:${JSON.stringify(getState())}`);
      //执行派发的动作
      next(action);
      //打印更新后的状态
      console.log(`新状态:${JSON.stringify(getState())}`);
    };
  };
}

redux-thunk
众所周知,redux在不使用任何中间件的情况下,每次派发的动作action必须是一个纯对象,例如:

add (value){
  return { type: 'add', payload: value }
}

所以说如果我们想在派发的过程中去执行一些方法,即派发一个函数,类似于下面的这种效果:

  asyncSetName(name) {
    //派发一个函数
    return (dispatch) => {
      //延迟两秒派发动作
      delay(2000).then(() => {
        dispatch({ type: types.ASYNC_SET_NAME, payload: name });
      });
    };
  }

我们就需要借助到react-thunk的功能,仔细想想,其实这个中间件实现不难,无非就是对派发出来的action做一个检测,实现如下:

export default function thunkMiddleware({ getState, dispatch }) {
  return function (next) {
    return function (action) {
      //如果派发的是一个函数
      if (typeof action === "function") {
        //直接执行,并且传入dispatch方法
        return action(dispatch);
      } else {
        //如果不是函数,交给下面一个中间件去处理
        next(action);
      }
    };
  };
}

redux-promise
redux-promise的作用顾名思义就是派发一个promise对象,可以通过参数resolve来触发action,例子如下:

  promiseSetName(dispatch, name) {
    return new Promise((resolve, reject) => {
      resolve({ type: types.PROMISE_SET_NAME, payload: name });
    });
  }

有了上面的例子,这个中间件也就依葫芦画瓢了,实现如下:

//检测是不是一个promise
function isPromise(obj) {
  return (
    !!obj &&
    (typeof obj === "object" || typeof obj === "function") &&
    typeof obj.then == "function"
  );
}

export default function promiseMiddleware({ getState, dispatch }) {
  return function (next) {
    return function (action) {
      // 判断action是不是一个标准的promise对象
      if (isPromise(action)) {
        // 如果action是一个promise 则将其resolve的值(action)进行dispatch
        action.then(dispatch);
      } else if (isPromise(action.payload)) {
        // 或者action.payload是一个promise 则将其resolve的值(action)进行dispatch
        action.payload
          .then(function (result) {
            dispatch({ ...action, payload: result });
          })
          .catch(function (error) {
            dispatch({ ...action, payload: error, error: true });
            return Promise.reject(error);
          });
      } else {
        //否者交给其他中间件来处理
        next(action);
      }
    };
  };
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值