在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是多么的重要。
网友评论