在React中,常用Redux来做一些业务逻辑处理。
Redux提供了中间件的写法,可以对Redux中的数据流做一些自定义的处理(类似于OKHttp的interceptor机制)。
创建中间件
中间件的语法是固定的, 它是一个三层的嵌套函数。 分别需要传递 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);
};
};
}
网友评论