# redux
# createStore
export default function createStore(
reducer,
initState,
rewriteCreateStoreFunc // 就是middraets
) {
if (rewriteCreateStoreFunc) {
const newCreateStore = rewriteCreateStoreFunc(createStore);
return newCreateStore(reducer, initState);
}
let state = initState;
let listeners = [];
function subscribe(listener) {
listeners.push(listener);
return function unsubscribe() {
const index = listeners.indexOf(listener);
listeners.splice(index, 1);
};
}
function getState() {
return state;
}
function dispatch(action) {
//reducer负责更新数据
state = reducer(state, action);
for (let i = 0; i < listeners.length; i++) {
const listener = listeners[i];
listener();
}
}
function replaceReducer(nextReucer) {
reducer = nextReucer;
dispatch({ type: Symbol() });
}
dispatch({ type: Symbol() });
return {
subscribe,
getState,
dispatch,
replaceReducer,
};
}
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
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
# combineReducers
把创建的 reducers 遍历,执行 reducer 函数,返回新的 state
export default function combineReducers(reducers) {
const reducerKeys = Object.keys(reducers);
return function combinaction(state = {}, action) {
const nextState = {};
for (let i = 0; i < reducerKeys.length; i++) {
const key = reducerKeys[i];
const reducer = reducers[key];
//现有 的状态
const previousStateForkey = state[key];
const nextStateForkey = reducer(previousStateForkey, action);
nextState[key] = nextStateForkey;
}
return nextState;
};
}
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
# applyMiddare
来看一下一个 middare
// 来看一下一个middare
const loggerMiddleware = (store) => (next) => (action) => {
console.log("this state", store.getState());
console.log("action", action);
next(action);
console.log("next state", store.getState());
};
export default loggerMiddleware;
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
applyMiddares 要把所有 middare 链接到 store 中
import compose from "./compose.js";
const applyMiddleware = function(...middlewares) {
return function(oldCreateStore) {
return function(reducer, initState) {
const store = oldCreateStore(reducer, initState);
const simpleStore = { getState: store.getState };
const chain = middlewares.map((middleware) => middleware(simpleStore));
const dispatch = compose(...chain)(store.dispatch);
return {
...store,
dispatch,
};
};
};
};
export default applyMiddleware;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
compose.js
export default function compose(...funcs) {
if (funcs.length === 0) {
return (arg) => arg;
}
if (funcs.length === 1) {
return funcs[0];
}
return funcs.reduce((a, b) => (...args) => a(b(...args)));
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# bindActionCreators
function bindActionCreator(actionCreator, dispatch) {
return function() {
return dispatch(actionCreator.apply(this, arguments));
};
}
export default function bindActionCreators(actionCreators, dispatch) {
const boundActionCreators = {};
for (const key in actionCreators) {
const actionCreator = actionCreators[key];
if (typeof actionCreator === "function") {
boundActionCreators[key] = bindActionCreator(actionCreator, dispatch);
}
}
return boundActionCreators;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
这个时候 index.js 这样使用
import exceptiontimeMiddleware from "./middlewares/exceptiontimeMiddleware.js";
import loggerMiddleware from "./middlewares/loggerMiddleware.js";
import timeMiddleware from "./middlewares/timeMiddleware.js";
//如上是中间件
import {
createStore,
combineReducers,
applyMiddleware,
bindActionCreators,
} from "./redux/index.js";
import counterReducer from "./reducers/counter.js";
import infoReducer from "./reducers/info.js";
import { increment } from "./actions/counter.js";
import { setName } from "./actions/info.js";
const reducer = combineReducers({
counter: counterReducer,
info: infoReducer,
});
const rewriteCreateStoreFunc = applyMiddleware(
exceptiontimeMiddleware,
timeMiddleware,
loggerMiddleware
);
const store = createStore(reducer, {}, rewriteCreateStoreFunc);
store.subscribe(() => {
const state = store.getState();
console.log(state.counter.count);
console.log(state.info.name);
});
console.log("✨", store);
// store.dispatch();
const actions = bindActionCreators({ increment, setName }, store.dispatch);
actions.increment();
actions.setName();
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
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
# action
function increment() {
return {
type: "INCREMENT",
};
}
export { increment };
1
2
3
4
5
6
2
3
4
5
6