Redux中间件原理解析
2020-03-08 本文已影响0人
Yezzle
在redux
项目开发过程中,有时候我们需要自己去编写一些redux
中间件, 但是中间件用法法一般都像下面这样子:
export function myMidware ({dispatch, getState}) {
// 返回一个接收dispatch为参数的函数
return (dispatch) => (action) => {
// do something
return dispatch(action)
}
}
//使用中间件
const store = createStore(reducer, applyMiddleware(myMidware))
一看到这种套娃的写法,整个人都是懵的。那么接下来我就带着问题给大家理解理解, 为什么中间件函数非要这么写, applyMiddleware
究竟做了什么
废话不多说首先来看看applyMiddleware
的源码,看看它到底做了啥:
// 首先这个函数接收多个中间件函数,放在middlewares的数组中
export default function applyMiddleware(...middlewares) {
// 返回一个接受createStore参数的函数, 这个函数执行之后应该返回一个增强版createStore函数
// (...args) => { ... } 这里可以看成是一个增强版的createStore函数(从createStore源码可以看出)
return createStore => (...args) => {
const store = createStore(...args)
// 这里的dispatch是不希望你在创建中间件的时候调用它
let dispatch = () => {
throw new Error(
'Dispatching while constructing your middleware is not allowed. ' +
'Other middleware would not be applied to this dispatch.'
)
}
// 把原版store的api构造成对象准备传递给中间件
const middlewareAPI = {
getState: store.getState,
dispatch: (...args) => dispatch(...args) // 个人感觉这里不给用 其实就没必要给到中间件构造函数里面去
}
// 把构造好的api对象传递给中间件,让中间件拥有可以访问store的能力
const chain = middlewares.map(middleware => middleware(middlewareAPI))
// compose函数可以把多个中间件函数的数组,合成一个中间件函数的形式,然后再执行中间件
// 并将得到的新的函数 当作新的dispatch函数
dispatch = compose(...chain)(store.dispatch)
// 返回一个增强了dispatch函数的store
return {
...store,
dispatch
}
}
}
从上面的代码解读可以看出, applyMiddleware
函数,做了已下事情:
- 返回一个新的
createStore
函数,这里叫它superCreateStore
函数 - 在
supterCreateStore
函数中,执行了createStore
函数,可见args
其实就是reducer
,看createStore
函数源码可知传入的就是reducer
-
superCreateStore
函数中执行中间件函数,得到了一个新的dispatch
函数,这里叫它superDispatch
- 最后
supterCreateStore
函数返回了一个新的store
对象,这个对象改造了dispatch
函数
看完了源码,接下来就开始理解这个思路了,套娃开始:
首先是applyMiddleware
-
createStore( reducer, enhancer)
返回一个store
-
applyMiddleware(...middleWares)
返回enhancer
增强器 -
enhencer
就是一个函数,接收createStore
为参数,返回一个superCreateStore
函数 -
superCreateStore
函数和createStore
一样,接手reducers
作为参数,返回一个新的store
再来理解中间件函数执行过程
- 在
superCreateStore
中,第一次执行中间传入了middlewareAPI
, 得到了dispatch
增强器 -
dispatch
增强器通过compose组合后,还是个dispatch增强器,再执行传入store.dispatch,也就是store原本的dispatch
函数作为参数 得到了superDispatch
函数
到此我们就已经完全理解了中间件的执行过程及其作用,其实就是返回了一个
dispatch
增强器函数的函数,得到的增强器函数接收dispatch
返回一个新的dispatch
函数,dispatch
执行后会返回action
,就是这样的逻辑, 这样我们就可以在action
被dispatch
到store
之前,做一些处理。
compose
函数正是一个链式调用dispatch
增强器的函数,每次执行一个函数都会返回一个增强过的dispatch
函数,给下一个中间件, 下面贴一下compose
函数的代码, 感兴趣的可以理解一下:
export default function compose(...funcs) {
if (funcs.length === 0) {
return arg => arg
}
if (funcs.length === 1) {
return funcs[0]
}
// 这里的args就是dispatch
return funcs.reduce((a, b) => (...args) => a(b(...args)))
}