Redux 学习笔记

createStore(reducer, initialState)

createStore 作用为创建一个 store,参数(总的 reducer,初始的状态树)
返回了 4 个方法挂在了 store 上

dispatch

主要有两个作用:

  1. 执行相应的 reducer
 currentState = currentReducer(currentState, action)

因为 store 只有一个,所以这里 currentState 为整个 store tree。
相应的 currentReducer 为根 reducer。

  1. 执行 subscribe 里注册的方法
  var listeners = currentListeners = nextListeners
  for (var i = 0; i < listeners.length; i++) {
    listeners[i]()
  }

在执行 subscribe 方法时,默认将 listen 函数放到了一个数组里,这里遍历这个数组,分别执行这些方法。

getState

作用:返回整个 state 树。

subscribe

function subscribe(listener) {
    nextListeners.push(listener);
}

作用:注册监听事件,返回 unsubscribe。

replaceReducer

作用:替换 reducer,重新初始化 store 结构。

createStore 里注册完这些函数后执行了 dispatch({ type: ActionTypes.INIT }) 初始化了 store tree,将每一个 store 分支下的 state 赋成初始值

combineReducer(reducer)

两个作用:

  1. 找到对应的 state 分支
  2. 将改变后的 state 合并回树里

传入的 reducer 是键值对的形式,首先用 Object.keys 取出所有的 key,筛选出所有符合条件的 reducer (值为一个函数),然后遍历符合条件的 key,取出对应的 key 和 reducer,执行这个 reducer,会返回当前分支下新的 state,判断当前分支下新的 state 是不是和原来的 state 引用相同,因为 reducer 中对于 state 的改变,会重新生成一个对象,不会与原来的对象引用相同。每次 dispatch 新的 action,都会遍历所有的 reducer,找到相应的方法,替换掉 store tree 上对应的 state,更新整个 store tree。

var nextState = {}
for (var i = 0; i < finalReducerKeys.length; i++) {
  var key = finalReducerKeys[i]
  var reducer = finalReducers[key]
  var previousStateForKey = state[key]
  var nextStateForKey = reducer(previousStateForKey, action)
  if (typeof nextStateForKey === 'undefined') {
    var errorMessage = getUndefinedStateErrorMessage(key, action)
    throw new Error(errorMessage)
  }
  nextState[key] = nextStateForKey
  hasChanged = hasChanged || nextStateForKey !== previousStateForKey
}
return hasChanged ? nextState : state

所以 combineReducer 还是遍历了所有的 reducer,更新了整个 store tree,因为在 createStore 的 dispatch 里需要返回整个的 state。作用是不用将每个页面对不同 action 的处理都写到一个文件再传到 createStore 里,可以不用页面写在不同的文件中,由它来判断改变更新。

dispatch(action) 中执行的是 combineReducer(rootState, action),然后进入 combineReducer 遍历所有的 reducer,分别执行,最终更新整个 store tree。