美文网首页
redux combineReducers 源码学习总结

redux combineReducers 源码学习总结

作者: strong9527 | 来源:发表于2017-09-12 17:05 被阅读33次

在redux的使用当中,我一直遇到一些自己无法解决的问题。其原因就是对于框架不了解,而且redux的源码也足够简单。所以通读一遍收获远远大于付出。

export default function combineReducers(reducers) {
  const reducerKeys = Object.keys(reducers)
  const finalReducers = {}
  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 (typeof reducers[key] === 'function') {
      finalReducers[key] = reducers[key]
    }
  }
  const finalReducerKeys = Object.keys(finalReducers)

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

  let shapeAssertionError
  try {
    assertReducerShape(finalReducers)
  } catch (e) {
    shapeAssertionError = e
  }
 //combineReducers实际返回的是一个函数。将敏感数据存储在闭包函数里面。
 //在dispatch的代码中调用的reducer函数就是这个函数。
  return function combination(state = {}, action) {
    if (shapeAssertionError) {
      throw shapeAssertionError
    }

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

    let hasChanged = false
    const nextState = {}
    
    
    //这个for非常关键,他是处理action的核心代码。
    //可以看到,redux处理action的方式就是遍历并调用所有定义的子reduer函数.
    //这样的处理方式保障可以保证所有的action请求都能找到相应的reducer进行处理.
    //但是定义的type一定要唯一否则可能对其他的reducer进行污染。
    

    for (let i = 0; i < finalReducerKeys.length; i++) {
      const key = finalReducerKeys[i]
      const reducer = finalReducers[key]
      const previousStateForKey = state[key]
      const nextStateForKey = reducer(previousStateForKey, action)
      if (typeof nextStateForKey === 'undefined') {
        const errorMessage = getUndefinedStateErrorMessage(key, action)
        throw new Error(errorMessage)
      }
      nextState[key] = nextStateForKey
      //直接将返回的state和之前的state进行地址对比,说明了redux判断状态是否改变是通过对象的浅相等。
      //在官网中,文档特意提出这是redux保障性能的关键。
      hasChanged = hasChanged || nextStateForKey !== previousStateForKey
    }
    return hasChanged ? nextState : state
  }
}

redux的浅比较对于代码结构的影响。

//一个简单的reducer函数
const initialState = {
    page: 1,
    size: 20,
    open: 1,
    order: 0,
    orderBy: 0,
    aggSize: 2000
}

export default function options(state = initialState, action = {}) {
    switch (action.type) {
        case PICTURES_TABRAND_OPTION:
            return merge({}, state, action.options)  
          //在对state的字段进行具体修改时,返回的一定是一个新的对象。而不是在原有state的基础上进行修改。
          //显然return merge(state, action.options)并不会触发redux改变state状态。
          //因为state的地址并没有变化。还是之前的对象。
          //这一点和react的state机制不同。react在比较setState后的数据比较时使用深比较。
        default :
            return state
    }
}


看完后就觉得immutable是多么的重要。

相关文章

网友评论

      本文标题:redux combineReducers 源码学习总结

      本文链接:https://www.haomeiwen.com/subject/zfgcsxtx.html