參考redux倉庫, redux-logger庫
所有1-8系列代碼倉庫
- 新建個項目吧 - 引入 redux, react-redux
中間件執行流程圖
演示代碼倉庫
就這個演示了,點擊 + 1 ,現在呢, 我想打印個日誌,就是每次點擊按鈕,都能打印出老的狀態和新的狀態
- 理邏輯,既然是在每次點擊事件之後打印,那麼,如果想拿到老的狀態,就需要在派發前,想拿到新的狀態,就是在派發後
先這樣寫:
let store = createStore(reducers);
let dispatch = store.dispatch;
store.dispatch = function(action) {
console.log(`老值: ${JSON.stringify(store.getState())}`);
dispatch(action);
console.log(`新值:${JSON.stringify(store.getState())}`);
};
export default store
這樣一來已經實現了,那上邊的代碼,核心就是重寫 了
redux的
dispatch方法
,
- 先存起來一份老的, 用於用戶的派發action
- 再重寫一份 dispatch 方法, 用於,在派發前和派發後做某些事
- 接着整個異步邏輯,點擊延時1秒再加1, 接着
重寫 dispatch
, 1秒後,再派發action
store.dispatch = function(action) {
setTimeout(() => {
dispatch(action);
}, 1000);
};
參考logger的實現第67行開始, 可以看到 連續返回了3個函數, 同時,第一個參數拿到getState, 第二個參數傳入老的 dispatch, 第三個參數就是reducer,接着實現一個簡化版logger中間件
function logger({ getState }) {
return function(next) {
return function(action) {
console.log(`老值: ${JSON.stringify(getState())}`);
next(action);
console.log(`新值: ${JSON.stringify(getState())}`);
};
};
}
let store = applyMiddleware(logger)(createStore)(reducers)
好了, 來接着推導 applyMiddleware
方法, 它接收的參數有 自己寫的 logger 中間件, redux的 createStore
方法, 還有自己的reducer
, 它連續返回了3個函數, 代碼實現就是下邊這樣的
// 傳入自己的中間件
function applyMiddleware(middleWare) {
// 傳入 redux 的 createStore 方法
return function(createStore) {
// 傳入自己的reducer
return function(reducer) {
let store = createStore(reducer);
// 包裹了一圈, 最後還是返回了 store因爲外部要接收store對象
// 此時,還沒有處理 中間件 middleWare 參數
return store;
};
};
}
處理 傳入的 middleWare
參數 (也就是中間件)
function applyMiddleware(middleWare) {
// 傳入 redux 的 createStore 方法
return function(createStore) {
// 傳入自己的reducer
return function(reducer) {
let store = createStore(reducer);
// 處理middleWare 參數, 看着上邊的 logger 函數寫
// 1. 先執行第一次傳入 store 實參, 供 logger 組件解構出 getState 參數
middleWare = middleWare(store)
// 再執行第二次 傳入 dispatch 供 next 使用派發action
let dispatch = middleWare(store.dispatch)
// 將這個與 store的 dispatch 進行替換掉
return {
...store,
dispatch
};
};
};
}
打印,實現了 單一中間件的處理,但實際開發中,中間件可能有多個的,下篇再接着聊