学习redux源码笔记记录

redux

代码片断

// todo.js
function todos(state = [], action) {
  switch (action.type) {
    case ADD_TODO:
      ...
      default:
        return state
  }
}

// reducer.js
import { combineReducers } from 'redux'
import todos from './todos'
import visibilityFilter from './visibilityFilter'

const rootReducer = combineReducers({
  todos,
  visibilityFilter
})

// index.js
import { createStore } from 'redux'
import reducer from './reducers'
...
const store = createStore(reducer)

复制代码
function createStore(reducer, preloadedState, enhancer) {
  let currentReducer = reducer
  let currentState = preloadedState
  let currentListeners = []
  let nextListeners = currentListeners
  let isDispatching = false
  
  function getState() {
    return currentState
  }
  
  function dispatch(action) {
  ...
    try {
      isDispatching = true
      // currentReducer即为combineReducers
      currentState = currentReducer(currentState, action)
    } finally {
      isDispatching = false
    }
    ...
  }
  
  dispatch({ type: ActionTypes.INIT })
  
  return {
    dispatch,
    getState,
    ...
  }
}

复制代码
// combineReducer.js
funciton combineReducer (reducers) {
  const reducerKeys = Object.keys(reducers)
  for (let i = 0; i < reducerKeys.length; i++) {
    const key = reducerKeys[i]
    ...
    if (typeof reducers[key] === 'function') {
      finalReducers[key] = reducers[key]
    }
  }
  const finalReducerKeys = Object.keys(finalReducers)
  return function combination(state = {}, action) {
  
    let hasChanged = false
    const nextState = {}
    for (let i = 0; i < finalReducerKeys.length; i++) {
      const key = finalReducerKeys[i]
      const reducer = finalReducers[key]
      const previousStateForKey = state[key]
      // previousStateForKey为undefined, action为{ type: ActionTypes.INIT }。 所以每一个reducer会执行default语句。
      const nextStateForKey = reducer(previousStateForKey, action)
      nextState[key] = nextStateForKey
      hasChanged = hasChanged || nextStateForKey !== previousStateForKey
    }
    return hasChanged ? nextState : state
  }

}

复制代码
  1. combineReducers函数对每一个reducer作校验,返回combination函数
  2. 在createStore中执行 dispatch({ type: ActionTypes.INIT })即执行combination函数。
  3. combination函数遍历执行每个reducer函数,const nextStateForKey = reducer(previousStateForKey, action)
  4. 在每一个reducer函数中,action为{ type: ActionTypes.INIT }, state为undefined
  5. state为undefined,所以会用默认值
  6. 本身定义的action中不会有与之对应的case语句,所以执行switch的default语句块中.

相关文章
相关标签/搜索