首先看下redux执行流程:
redux设计思想:
(1)Reducer:纯函数,只承担计算 State 的功能,不合适承担其他功能,也承担不了,因为理论上,纯函数不能进行读写操作。
(2)View:与 State 一一对应,可以看作 State 的视觉层,也不合适承担其他功能。
(3)Action:存放数据的对象,即消息的载体,只能被别人操作,自己不能进行任何操作。
想来想去,只有发送 Action 的这个步骤,即store.dispatch()
方法,可以添加功能。
中间件根本原理:对store.dispatch
进行改造。
中间件出现的原因:由于很多时候执行dispatch并不仅仅是立即去更新reducer,这时需要执行其他函数来满足项目需求,这些函数就是中间件,最后执行过一系列中间件后再去执行reducer
举例来说,要添加日志功能,把 Action 和 State 打印出来,可以对store.dispatch
进行如下改造。
let next = store.dispatch;
store.dispatch = function dispatchAndLog(action) {
console.log('dispatching', action);
next(action);
console.log('next state', store.getState());
}
上面代码中,对store.dispatch
进行了重定义,在发送 Action 前后添加了打印功能。这就是中间件的雏形。
中间件就是一个函数,对store.dispatch
方法进行了改造,在发出 Action 和执行 Reducer 这两步之间,添加了其他功能。
————————————————————————————————————————————
applyMiddlewares的作用:它是 Redux 的原生方法,作用是将所有中间件组成一个数组,依次执行。
源码:
export default function applyMiddleware(...middlewares) {
return (createStore) => (reducer, preloadedState, enhancer) => {
var store = createStore(reducer, preloadedState, enhancer);
var dispatch = store.dispatch;
var chain = [];
var middlewareAPI = {
getState: store.getState,
dispatch: (action) => dispatch(action)
};
chain = middlewares.map(middleware => middleware(middlewareAPI));
dispatch = compose(...chain)(store.dispatch);
return {...store, dispatch}
}
}
//执行顺序解析
//中间件数组传入{getState: store.getState,dispatch: (action) => dispatch(action)} =>
//compose合并新中间件数组 并传入dispatch=>
//执行完所有中间件函数后返回store和dispatch
applyMiddlewares调用实例:返回store对象
let middlewares = [loggerMiddleware, thunkMiddleware, ...others];
let store = applyMiddleware(middlewares)(createStore)(reducer, initialState);