redux源码学习--applyMiddleware
2018/5/12 Javascriptreactredux
applyMiddleware理解
中间件的本质是作为enhancer而存在的。它是通过createStore方法传递到redux的内部中的,中间件模块是一个高阶函数 下面是redux中间件的基本格式:
const reduxMiddleware = ({dispatch, getState}[简化的store]) => (next[上一个中间件的dispatch方法]) => (action[实际派发的action对象]) => {}
export default function applyMiddleware(...middlewares) {
// middlewares就是我们传递给applyMiddlewarez函数的一系列中间件函数
return (createStore) => (...args) => {
// createStore就是redux用于创建store的方法,args === [reducers, preloadedState]。下面这句话就是在中间件的内部,使用我们传递的参数创建一个store对象
// 注:这一块没有传递enhancer,所以返回的就是我们经常使用的store对象
const store = createStore(...args)
// 获取store对象的dispatch方法
let dispatch = () => {
throw new Error(
`Dispatching while constructing your middleware is not allowed. ` +
`Other middleware would not be applied to this dispatch.`
)
}
// 传递给中间件的第一层的函数的参数,
const middlewareAPI = {
getState: store.getState,
// 重写了dispatch方法,其实就是store.dispatch(...args)
dispatch: (...args) => dispatch(...args)
}
/**
* 着重给大家详细的解释一下这一块
* 假设我们给applyMiddleware函数传递的中间件是
* applyMiddleware(
* f1 => g1 => h1(...arg) => {},
* f2 => g2 => h2(...arg) => {}
* )
* 运行下面的这行代码之后,chain中保存的内容是
* chain = [g1 => h1(...arg) => {}, g2 => h2(...arg) => {}]
*/
const chain = middlewares.map(middleware => middleware(middlewareAPI))
/**
* 当我们把chain传入到 compose中后,根据我们对compose的分析,
* compose(...chain)(store.dispatch)的结果就是:
* g1(h2(...arg)) => h1(...arg)
*
* 也就是说,按照上面的这个形式,下面的dispatch和h1函数是一样的,所以,h1的参数,就是我们需要派发的action,当我们调用dispatch的时候,其实就相当于调用h1(action),而在h1的内部,这个action是由g1的参数
* 也就是h2进行派发的,所以这个时候action就传递到了h2的内部,而h2的参数是由g2的参数,也就是实际传入的store.dispatch进行派发的,就这样层层传入,层层输出,就形成了我们强大的中间件机制。
*/
dispatch = compose(...chain)(store.dispatch)
// 返回的也是一个store对象
return {
...store,
// 这个dispatch其实就是,各个中间件的最底层(第三层)的哪个函数组成的圆环函数构成的
dispatch
}
}
}