eg:使用代码
//reducers/todos.js
export default function todos(state = [], action) {
switch (action.type) {
case 'ADD_TODO':
return state.concat([action.text])
default:
return state
}
}
//reducers/counter.js
export default function counter(state = 0, action) {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return state
}
}
//reducers/index.js
import { combineReducers } from 'redux'
import todos from './todos'
import counter from './counter'
export default combineReducers({
todos,
counter
})
//App.js
import { createStore } from 'redux'
import reducer from './reducers/index'
let store = createStore(reducer)
console.log(store.getState())
// {
// counter: 0,
// todos: []
// }
store.dispatch({
type: 'ADD_TODO',
text: 'Use Redux'
})
console.log(store.getState())
// {
// counter: 0,
// todos: [ 'Use Redux' ]
// }
//源码分析
export default function combineReducers(reducers) {
/**获取reducers的key */
const reducerKeys = Object.keys(reducers)
const finalReducers = {}
for (let i = 0; i < reducerKeys.length; i++) {
const key = reducerKeys[i]
...
/**将传入的reducers赋值给 finalReducers*/
if (typeof reducers[key] === 'function') {
finalReducers[key] = reducers[key]
}
}
/**获取所有的finalReducerKeys */
const finalReducerKeys = Object.keys(finalReducers)
...
let shapeAssertionError
try {
assertReducerShape(finalReducers)
} catch (e) {
shapeAssertionError = e
}
/*返回合并后的新的reducer函数*/
return function combination(state = {}, action) {
if (shapeAssertionError) {
throw shapeAssertionError
}
...
let hasChanged = false
const nextState = {}
/**遍历执行所有的reducers*/
for (let i = 0; i < finalReducerKeys.length; i++) {
const key = finalReducerKeys[i]
const reducer = finalReducers[key]
/**获取到之前的state */
const previousStateForKey = state[key]
/**生成新的state */
const nextStateForKey = reducer(previousStateForKey, action)
if (typeof nextStateForKey === 'undefined') {
const errorMessage = getUndefinedStateErrorMessage(key, action)
throw new Error(errorMessage)
}
/**将新的当前reducer的state赋值给总的state */
nextState[key] = nextStateForKey
/**判断当前reducer对应是否state发生变化 */
hasChanged = hasChanged || nextStateForKey !== previousStateForKey
}
/**如果有一个state发生变化则返回新的state,否则返回旧的state */
return hasChanged ? nextState : state
}
}