# applyMiddleware 实现
使用包含自定义功能的 middleware(中间件) 来扩展 Redux 是一种推荐的方式
# 如何使用
let createStoreWithMiddleware = applyMiddleware(
reduxThunk,
logger,
)(createStore);
let store = createStoreWithMiddleware(reducer);
1
2
3
4
5
2
3
4
5
可以看到 我们传入中间件,createStore,返回的好像重写的 createStore。其实重写的不是 createStore,而是 dispatch。

# applyMiddleware 代码
function compose(...funcs) {
//如果没有中间件
if (funcs.length === 0) {
return (arg) => arg;
}
//中间件长度为1
if (funcs.length === 1) {
return funcs[0];
}
return funcs.reduce((prev, current) => (...args) => prev(current(...args)));
}
const applyMiddleware = (...middlewares) => (createStore) => (...args) => {
let store = createStore(...args);
let dispatch;
const middlewareAPI = {
getState: store.getState,
dispatch: (...args) => dispatch(...args),
};
//将 getState,dispatch 传给middleware
let middles = middlewares.map((middleware) => middleware(middlewareAPI));
dispatch = compose(...middles)(store.dispatch);
return {
...store,
dispatch,
};
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
这里是重写 dispatch 但是如何重写的让我先看 middleware 如何实现的
# logger
const logger = (store) => (next) => (action) => {
if (typeof action !== "function") {
console.log("dispatching", action);
}
let result = next(action);
console.log("next state", store.getState());
return result;
};
/**为了好演示 我们把每个函数起个名字**/
// fn1 = next => action => {...}
// fn2 = action => {...}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
applyMiddleware 中的 middles = [fn1,fn1,fn1],一个 fn1 函数的数组
# compose(...middles)得到的是什么?
compose 饶,但是不复杂可以自己打断看
compose(...middles)得到的是这么一个函数
function(...args){
return fn1(fn1(fn1(...args)))
}
1
2
3
2
3
这个 fn1 是数组由左到右,对应着函数 又外到内.
# compose(...middles)(store.dispatch) 得到的是什么?
dispatch = fn1(fn1(fn1(dispatch))); //这个返回值是什么?
1
此时dispatch 就变成了
function (action){
//...
next(action)
//此时的next 就是上面的fn2
//...
}
1
2
3
4
5
6
2
3
4
5
6
可以理解成 从右到左 每个 fn2 都是 一个包裹的 dispatch,然后当成参数传给它左边的函数。
至此,中间件 结束
# combineReducers
这个实现不复杂直接贴代码好了
function combineReducers(reducers) {
return function combination(state = {}, action) {
let nextState = {};
let hasChanged = false; //状态是否改变
for (let key in reducers) {
const previousStateForKey = state[key];
const nextStateForKey = reducers[key](previousStateForKey, action);
nextState[key] = nextStateForKey;
//只有所有的 nextStateForKey 均与 previousStateForKey 相等时,hasChanged 的值才是 false
hasChanged = hasChanged || nextStateForKey !== previousStateForKey;
}
//state 没有改变时,返回原对象
return hasChanged ? nextState : state;
};
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
← redux实现 react-redux实现 →