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
  }
}

  

 

posted @ 2020-04-12 19:20  前端++  阅读(210)  评论(0编辑  收藏  举报