// 将各个分片整合到总的 reducer 中
function combineReducers(reducerMap) {
const reducerKeys = Object.keys(reducerMap)
const reducer = (state = {}, action) => {
let newState = {}
for (let i = 0; i < reducerKeys.length; i++) {
const key = reducerKeys[i];
const currentReducer = reducerMap[key]
const prevState = state[key]
newState[key] = currentReducer(prevState, action)
}
return newState
}
return reducer
}
// 基础的发布订阅模型
function createStore(reducer) {
let state
let listeners = [];
function getState() {
return state
}
function subscribe(callback) {
listeners.push(callback)
}
function dispatch(action) {
state = reducer(state, action)
for (let i = 0; i < listeners.length; i++) {
const listener = listeners[i];
listener()
}
}
const store = {
getState,
subscribe,
dispatch
}
// 初始化 state
state = reducer(state, {
type: '@@init/xxx'
})
return store
}
// 创建 Redux 对象并挂载到全局
window.Redux = {}
Redux.combineReducers = combineReducers
Redux.createStore = createStore
function todos(state = [], action) {
switch (action.type) {
case 'ADD_TODO':
return state.concat([action.text])
default:
return state
}
}
function counter(state = 0, action) {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return state
}
}
let reducer = Redux.combineReducers({ todos, counter })
let store = Redux.createStore(reducer)
store.subscribe(() => { console.log(store.getState()) })
入口文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="01.js"></script>
</head>
<body>
<script src="02.js"></script>
</body>
</html>