redux教程之源码解析2 combineReducers(分析在注释中)
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 } }
前端笔记0-0