middleware作用:
在到达原始reducer之前通过middleware做一些处理。middleware通过next将控制权传递到下一个middleware,直到到达原始reducer,再依次返回执行剩余部分
middleware.png
创建一个middleware:
const exampleMiddleware =
store => // 注入的middlewareAPI
next => action => {
console.log('dispatching', action);
// get oldState
console.log('before state', store.getState())
// 触发真实的action
let result = next(action);
// get newState
console.log('next state', store.getState());
return result;
};
使用
applyMiddleware(exampleMiddleware, exampleMiddleware1, ...)
applyMiddleware源码:
// applyMiddleware
export default function applyMiddleware(...middlewares) {
return (createStore) => (reducer, preloadedState, enhancer) => {
const store = createStore(reducer, preloadedState, enhancer)
// 保存store中原有的dispatch
let dispatch = store.dispatch
let chain = []
const middlewareAPI = {
getState: store.getState,
dispatch: (action) => dispatch(action)
}
// 将middlewareAPI注入到middleware中
chain = middlewares.map(middleware => middleware(middlewareAPI))
// store.dispatch即为最后一个middleware的next,解释如下
// eg: chain=[funcA, funcB, funcC, funcD]
// compose(...chain)(store.dispatch) => funcA(funcB(func(funcD(store.dispatch))))
// 可去官网看compose源码
dispatch = compose(...chain)(store.dispatch)
return {
...store,
dispatch
}
}
}
compose(...chain)(store.dispatch)解释:
compose源码
假设A,B,C分别为3个middleware
compose(A, B, C)(dispatch)('action')
等同于A(B(C(dispatch)))('action');
// middleware A
function A(next) {
// console.log(`A-${s}`);
return function A_action(action) {
console.log('a_middleware_start');
// next指的是B_action
let ret = next(action);
console.log(`next(action) result: ${ret}`)
console.log('a_middleware_end')
}
}
// middleware B
function B(next) {
// console.log(`B-${s}`);
return function B_action(action) {
console.log('b_middleware_start');
// next指的是C_action
let ret = next(action);
console.log(`next(action) result: ${ret}`)
console.log('b_middleware_end');
return 'b-ret'
}
}
// middleware C
function C(next) {
// console.log(`C-${s}`);
return function C_action(action) {
console.log('c_middleware_start');
// 如果在next函数中加return,则会获取到下一个middleware的执行结果
// next指的是传进来的参数:dispatch函数
let ret = next(action);
console.log(`next(action) result: ${ret}`)
console.log('c_middleware_end');
return 'c-ret'
}
}
function dispatch(action) {
// original dispatch
console.log('original dispatch invoke');
// 将结果返回。redux dispatch中直接将action对象返回
return action
}
A(B(C(dispatch)))('action');
// 结果如下
// a_middleware_start
// b_middleware_start
// c_middleware_start
// original dispatch invoke
// c_next(action) result: action
// c_middleware_end
// b_next(action) result: c-ret
// b_middleware_end
// a_next(action) result: b-ret
// a_middleware_end