# 写个Redux
使用 Redux 之后就会发现 Redux 几个关键的 API:
- createStore - 创建 store,并返回一些方法 getState, dispatch;
- combineReducers - 将多个Reducer聚合在一起;
- bindActionCreators - 生成可以dispatch 指定 action 的方法
- applyMiddleware - 使用中间件
# createStore
function createStore(reducers, initialState, enhance) {
// 有中间件的情况
if (enhance) {
return enhance(createStore)(reducers, initialState);
}
let state = initialState || {};
let listeners = [];
function getState() {
return state;
}
function dispatch(action) {
// 触发reducer
state = reducers(state, action);
// 触发监听逻辑 相当于 发布事件
listeners.forEach((listener) => {
listener();
});
return action;
}
// 订阅
function subscribe(listener) {
listeners.push(listener);
return function unsubscribe() {
// 移除订阅
const index = listeners.indexOf(listener);
listeners.splice(index, 1);
}
}
return {
getState,
dispatch,
subscribe,
};
}
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# combineReducers
function combineReducers(reducers) {
const finalReducers = { ...reducers };
return function combination(state, action) {
let hasChanged = false;
const newState = {};
Object.keys(finalReducers).forEach((key) => {
const reducer = finalReducers[key];
const preStateForKey = state[key];
// 执行单个reducer 并返回结果
const nextStateForKey = reducer(preStateForKey, action);
// 结果的浅对比
hasChanged = hasChanged || nextStateForKey !== preStateForKey;
newState[key] = nextStateForKey;
});
// 只有变化的时候才更新
return hasChanged ? newState : state;
};
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# bindActionCreators
function bindActionCreators(actionCreators, dispatch) {
const boundActionCreators = {};
// 遍历 actionCreators,并为其生成 dispatcher
Object.keys(actionCreators).forEach((actionCreator) => {
boundActionCreators[actionCreator] = function (...rest) {
const action = actionCreator.at.call(this, ...rest);
dispatch(action);
};
});
return boundActionCreators;
}
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
function applyMiddleware(...middlewares) {
// 返回柯里化函数
return (createStore) => (reducer, initialState) => {
// 执行createStore 获取store
const store = createStore(reducer, initialState);
const { getState, dispatch } = store;
const middlewareChain = middlewares.map((middleware) => middleware({ state: getState }));
// 串行调用 中间件并返回新的dispatch,即增强dispatch
const newDispatcher = middlewareChain.reduceRight((last, crt) => crt(last), dispatch);
return {
...store,
dispatch: newDispatcher,
};
};
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
← redux