理解Redux中间件

redux的中间件相当于改写store的dispatch方法。
redux-applyMiddleware源代码

export default function applyMiddleware(...middlewares) { return createStore => (...args) => { const store = createStore(...args) let dispatch = () => { throw new Error( `Dispatching while constructing your middleware is not allowed. ` + `Other middleware would not be applied to this dispatch.` ) } let chain = []const middlewareAPI = { getState: store.getState, dispatch: (...args) => dispatch(...args) } chain = middlewares.map(middleware => middleware(middlewareAPI)) dispatch = compose(...chain)(store.dispatch)return { ...store, dispatch } } }

【理解Redux中间件】通过以下两行源码
chain = middlewares.map(middleware => middleware(middlewareAPI)) dispatch = compose(...chain)(store.dispatch)

可推导出redux给middleware函数暴露了通用的api,所有的middleware必须写成
export default ({getState, dispatch} => next => { ... })

其中next函数就是store的dispatch的引用,中间件内部可以使用。此后dispatch方法会被改写,中间件内部的dispatch也是改写后的dispatch。
redux-thunk源码
function createThunkMiddleware(extraArgument) { return ({ dispatch, getState }) => next => action => { if (typeof action === 'function') { return action(dispatch, getState, extraArgument); }return next(action); }; }const thunk = createThunkMiddleware(); thunk.withExtraArgument = createThunkMiddleware; export default thunk;

redux-thunk就是通过改写dispatch方法实现兼容异步更改state的。注意next才是redux本身的dispatch方法的引用,中间件中的dispatch是compose(...chain)(store.dispatch)的返回值,已经被改写了。

    推荐阅读