Combined Reducers

Combined Reducers does combining reducers. That's it. The Most of codes on combineReducers.js is error handling.

Here is the steps of combining reducers.

  1. Get keys of each reducers.
  2. Iterate reducers and check wether reducers have keys and are functions.
  3. Put valid reducers to finalReducers object.
  4. Return function combination() which will be invoked every time action is dispatched.
  5. Fromcombination(), finalReducers will be iterated and each reducers will be invoked and the store new state on `newState` object by key.
  6. It tracks state was changed and compare new entire state newState and previous entire state previousState. If it was changed, return new state newState.
  // 1. get keys of reducers
  const reducerKeys = Object.keys(reducers)


  const finalReducers = {}


  // 2. Iterate reducers and check reducers have keys and are functions

  for (let i = 0; i < reducerKeys.length; i++) {
    const key = reducerKeys[i]

    if (process.env.NODE_ENV !== 'production') {
      if (typeof reducers[key] === 'undefined') {
        warning(`No reducer provided for key "${key}"`)
      }
    }

    // If it is function or not a assign to final reducers

    if (typeof reducers[key] === 'function') {
      finalReducers[key] = reducers[key]
    }
  }



  // 3. Extract keys from 'finalReducers' object  
  const finalReducerKeys = Object.keys(finalReducers)


  /* 
    Error handling
  */

  let unexpectedKeyCache
  if (process.env.NODE_ENV !== 'production') {
    unexpectedKeyCache = {}
  }

  let shapeAssertionError
  try {
    assertReducerShape(finalReducers)
  } catch (e) {
    shapeAssertionError = e
  }


  /*
    - combination
    @params state
    @params action
  */


  return function combination(state = {}, action) {

    /*

      Error handling phase

    */

    if (shapeAssertionError) {
      throw shapeAssertionError
    }

    if (process.env.NODE_ENV !== 'production') {
      const warningMessage = getUnexpectedStateShapeWarningMessage(
        state,
        finalReducers,
        action,
        unexpectedKeyCache
      )
      if (warningMessage) {
        warning(warningMessage)
      }
    }



    let hasChanged = false

    // Store new state
    const nextState = {}


    /*

      Iterate finalReducer and execute each reducers

    */

    for (let i = 0; i < finalReducerKeys.length; i++) {

      const key = finalReducerKeys[i]

      const reducer = finalReducers[key]

      const previousStateForKey = state[key]

      /*
        Getting next state state by running reducer function. 

        function reducer(state = {}, action) {
          switch(aciton.type): {
            case: ''
              return Object.assing({}, state, action.payload)
          }
        }

      */

      const nextStateForKey = reducer(previousStateForKey, action)

      // reducer function returns new state and nextStateForKey has new state.
      // If it is undefined, throw Error.

      if (typeof nextStateForKey === 'undefined') {
        const errorMessage = getUndefinedStateErrorMessage(key, action)
        throw new Error(errorMessage)
      }

      // Put nextStateForkey to new state object

      nextState[key] = nextStateForKey

      // If it is different object from previousStateForKey assign true to hasChanged

      hasChanged = hasChanged || nextStateForKey !== previousStateForKey


    }

    // if it is changed, return newState

    return hasChanged ? nextState : state
  }
}

results matching ""

    No results matching ""