在React中郭赐,常用Redux來做一些業(yè)務邏輯處理率触。
Redux提供了中間件的寫法母蛛,可以對Redux中的數(shù)據(jù)流做一些自定義的處理(類似于OKHttp的interceptor機制)。
創(chuàng)建中間件
中間件的語法是固定的, 它是一個三層的嵌套函數(shù)腕柜。 分別需要傳遞 store,next,action寿羞。store層主要的是我們需要獲取store對象猖凛。中間件的鏈式調(diào)用主要通過對next的層層加工來實現(xiàn),所以要有next層绪穆。之所以需要action辨泳,是因為我們最終還是個dispatch函數(shù),最終還是需要action參數(shù)的玖院。
export default store => next => action => {
//action前的狀態(tài)
//做你想做的操作
const returnValue = next(action);
//action后的狀態(tài)
//做你想做的操作
...
return returnValue;
}
加載中間件
當我們想讓Redux啟用某一個中間件的時候菠红,需要在創(chuàng)建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
});
};
};
}
參數(shù)是...Function 類型难菌,也就是多個Function類型的參數(shù)试溯,每個都是一個要放到Store處理鏈中的中間件。返回的是一個Store Enchancer郊酒,當創(chuàng)建store的時候會傳遞過去遇绞。
chain = middlewares.map(function (middleware) {
return middleware(middlewareAPI);
});
...
_dispatch = _compose2["default"].apply(undefined, chain)(store.dispatch);
經(jīng)過上面的兩層調(diào)用,生成了新的dispatch燎窘。 之前我們提到過中間件是三層嵌套的函數(shù)摹闽,那么它的第三層調(diào)用是在哪呢? 沒錯褐健,生成的dispatch會在Redux組件中被調(diào)用付鹿!
中間件是可以鏈式調(diào)用的,它是通過next()來實現(xiàn)的蚜迅。next()其實就是當前中間件處理之后要返回的dispatch舵匾,返回后后面的中間件會對其繼續(xù)處理,繼續(xù)返回處理后的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,一般會是個異步函數(shù)亡蓉,在此調(diào)用
//如果不是function類型的action晕翠,通過next直接傳遞給其他middleware
return typeof action === 'function' ? action(dispatch, getState) : next(action);
};
};
}