學習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語句塊中.

相關文章
相關標籤/搜索