转载的~react

Redux中间件

2017-03-19  本文已影响78人  VictorLiang

在React中,常用Redux来做一些业务逻辑处理。
Redux提供了中间件的写法,可以对Redux中的数据流做一些自定义的处理(类似于OKHttp的interceptor机制)。

9c456d5d211602e9d742262c2bf45762_b.png-23.6kB9c456d5d211602e9d742262c2bf45762_b.png-23.6kB

创建中间件

中间件的语法是固定的, 它是一个三层的嵌套函数。 分别需要传递 store,next,action。store层主要的是我们需要获取store对象。中间件的链式调用主要通过对next的层层加工来实现,所以要有next层。之所以需要action,是因为我们最终还是个dispatch函数,最终还是需要action参数的。

export default store => next => action => {
    //action前的状态
    //做你想做的操作
    const returnValue = next(action);
    //action后的状态
    //做你想做的操作
    ...
    
    return returnValue;
}

加载中间件

当我们想让Redux启用某一个中间件的时候,需要在创建Store的时候生命需要应用那些中间件。

    const middleware = applyMiddleware(Middleware1, Middleware2...);
    return createStore(combinedReducer, initData, middleware)

具体applyMiddleware的逻辑:

/*
* @param {...Function} middlewares The middleware chain to be applied.
 * @returns {Function} A store enhancer applying the middleware.
 */
function applyMiddleware() {
  for (var _len = arguments.length, middlewares = Array(_len), _key = 0; _key < _len; _key++) {
    middlewares[_key] = arguments[_key];
  }

  return function (createStore) {
    return function (reducer, initialState, enhancer) {
      var store = createStore(reducer, initialState, enhancer);
      var _dispatch = store.dispatch;
      var chain = [];

      var middlewareAPI = {
        getState: store.getState,
        dispatch: function dispatch(action) {
          return _dispatch(action);
        }
      };
      chain = middlewares.map(function (middleware) {
        //解三层嵌套的第一层
        return middleware(middlewareAPI);
      });
      //解三层嵌套的第二层
      _dispatch = _compose2["default"].apply(undefined, chain)(store.dispatch);

      return _extends({}, store, {
        dispatch: _dispatch
      });
    };
  };
}

参数是...Function 类型,也就是多个Function类型的参数,每个都是一个要放到Store处理链中的中间件。返回的是一个Store Enchancer,当创建store的时候会传递过去。

chain = middlewares.map(function (middleware) {
        return middleware(middlewareAPI);
      });
...
_dispatch = _compose2["default"].apply(undefined, chain)(store.dispatch);

经过上面的两层调用,生成了新的dispatch。 之前我们提到过中间件是三层嵌套的函数,那么它的第三层调用是在哪呢? 没错,生成的dispatch会在Redux组件中被调用!
中间件是可以链式调用的,它是通过next()来实现的。next()其实就是当前中间件处理之后要返回的dispatch,返回后后面的中间件会对其继续处理,继续返回处理后的dispatch。

Redux-Thunk

Redux-Thunk的代码极其精简(注释)。 好机智的一个套路,感觉要上天。

//_ref 与我们之前applyMiddleware之中的 middlewareAPI是不是对应上了啊!!
function thunkMiddleware(_ref) {
  var dispatch = _ref.dispatch;
  var getState = _ref.getState;

  return function (next) {
    return function (action) {
      //Thunk 的action可不是plain text了,而是个function
      //Thunk 对应的action,一般会是个异步函数,在此调用
      //如果不是function类型的action,通过next直接传递给其他middleware
      return typeof action === 'function' ? action(dispatch, getState) : next(action);
    };
  };
}
上一篇下一篇

猜你喜欢

热点阅读