前言
最近看了一下Redux的官方文档,突然感觉以前忽略了很多东西,现在回头看看,正好记录一下,并且加深印象
中间件的使用
const store = createStore(reducers,applyMiddleware(logger));
以上是应用了redux-logger中间件的代码,只要按照官方提供的规定格式实现,并应用到中间件方法,那么,在执行一个action的时候,就会调用中间件。
在官方的示例中,有一个logger实现的示例
const logger = store => next => action =>{
console.log('prev state',store.getState())
console.log('dispatch',action);
let result = next(action);
console.log('next state',store.getState());
return result;
}
从这个示例可以看出,实现一个中间件需要做一下几件事情:
- 三层函数包装:第一层传入store,第二层传入下一个中间件next,第三层传入此次执行的action;
2.在最内层的函数实现中,需要调用next中间件,并返回结果。
原理解析
首先来看一下createStore
- createStore(reducer, preloadedState, enhancer)
createStore有三个参数1.reducer;2.preloadedState;3.enhancer
reducer :即一些改变state的纯函数,这个可以在官方文档查看具体定义;
preloadesState:是初始化的state,这个state可以是加载页面时从服务器提供的初始化state值,这个为服务器端渲染,并与客户端保持数据一致提供可能;
enhancer: store增强功能,在redux中特指applyMiddleware()方法的返回值;
来看看createStore方法的开头部分
if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {
enhancer = preloadedState
preloadedState = undefined
}
if (typeof enhancer !== 'undefined') {
if (typeof enhancer !== 'function') {
throw new Error('Expected the enhancer to be a function.')
}
return enhancer(createStore)(reducer, preloadedState)
}
if (typeof reducer !== 'function') {
throw new Error('Expected the reducer to be a function.')
}
这里面第二个判断if中有enhancer为function则调用enhander(createStore)(reducer,preloadedState);我们都知道enhancer 是applyMiddleware方法的返回值,
下面在看applyMiddleware方法
- applyMiddleware(...middlewares)
参数即为所有要使用的符合redux的中间件;
apllyMiddleware的代码很精简
export default function applyMiddleware(...middlewares) {
return (createStore) => (reducer, preloadedState, enhancer) => {
const store = createStore(reducer, preloadedState, enhancer)
let dispatch = store.dispatch
let chain = []
const middlewareAPI = {
getState: store.getState,
dispatch: (action) => dispatch(action)
}
chain = middlewares.map(middleware => middleware(middlewareAPI))
dispatch = compose(...chain)(store.dispatch)
return {
...store,
dispatch
}
}
}
来分析一下applyMiddleware方法,
- 接收一个middleware数组作为参数,返回一个方法,我们暂且叫它enhancer;
- enhancer仍然是一个方法,他接收createStore方法作为参数,enhancer方法返回的还是一个方法,这个方法的参数与createStore方法的的签名一样,都包含三个参数,分别是reducer, preloadedState, enhancer;我们叫它mergeDispatch;
- mergeDispatch这个最终的方法的作用有2点,首先调用createStore创建store,然后就是不断的替换store.dispatch,以达到应用中间件的目的,大概流程如下:
最终就是把原始的store.dispatch应用到所有的中间件的最核心的位置调用,其他的插件都在原始的dispatch外层包裹着。