成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

redux源碼分析之二:combineReducers.js

big_cat / 2794人閱讀

摘要:歡迎關注源碼分析系列文章源碼分析之一源碼分析之二源碼分析之三源碼分析之四源碼分析之五文件對外暴露了一個函數(shù),函數(shù)是的一個輔助性的函數(shù),用于拆分里面的第一個參數(shù)函數(shù)。函數(shù)的返回值是一個函數(shù),該函數(shù)是組合之后的一個標準的函數(shù)。

歡迎關注redux源碼分析系列文章:
redux源碼分析之一:createStore.js
redux源碼分析之二:combineReducers.js
redux源碼分析之三:bindActionCreators.js
redux源碼分析之四:compose.js
redux源碼分析之五:applyMiddleware

combineReducers.js文件對外暴露了一個函數(shù)combineReducers,combineReducer函數(shù)是redux的一個輔助性的函數(shù),用于拆分createStore里面的第一個參數(shù):reducer函數(shù)。combineReducer函數(shù)的返回值是一個函數(shù),該函數(shù)是組合之后的一個標準的reducer函數(shù)。

一、分析combineReducers函數(shù)的參數(shù):

combineReducers函數(shù)僅包含一個參數(shù)reducers,reducers是一個object類型參數(shù),比如:

let reducers = {
    users: function getUsersReducer(){}, 
    userInfo: function getUserInfoReducer(){}
}
二、分析combineReducers返回之前做了什么:

1、從傳入的參數(shù)里面提取出合法的reducers(reducers的每一個key對應的value值是函數(shù),才是合法的子reducer),賦值給新的局部變量:finalReducers

  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}"`)
      }
    }
    //過濾出reducers對應的value值是function的key,將其放入finalReducers對象
    if (typeof reducers[key] === "function") {
      finalReducers[key] = reducers[key]
    }
  }

2、校驗finalReducers, 判斷其每一個子reducer是否能返回正常的子state

  //取出過濾出來的有效的keys列表
  const finalReducerKeys = Object.keys(finalReducers)

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

  let shapeAssertionError
  try {
    assertReducerShape(finalReducers)
  } catch (e) {
    shapeAssertionError = e
  }

assertReducerShape函數(shù):

//確認reducer是否是合法的reducer,即返回的state是不是undefined,如果是undefined,則是非法reducer
function assertReducerShape(reducers) {
  Object.keys(reducers).forEach(key => {
    const reducer = reducers[key]
    const initialState = reducer(undefined, {type: ActionTypes.INIT})

    if (typeof initialState === "undefined") {
      throw new Error(
        `Reducer "${key}" returned undefined during initialization. ` +
        `If the state passed to the reducer is undefined, you must ` +
        `explicitly return the initial state. The initial state may ` +
        `not be undefined. If you don"t want to set a value for this reducer, ` +
        `you can use null instead of undefined.`
      )
    }

    const type = "@@redux/PROBE_UNKNOWN_ACTION_" + Math.random().toString(36).substring(7).split("").join(".")
    if (typeof reducer(undefined, {type}) === "undefined") {
      throw new Error(
        `Reducer "${key}" returned undefined when probed with a random type. ` +
        `Don"t try to handle ${ActionTypes.INIT} or other actions in "redux/*" ` +
        `namespace. They are considered private. Instead, you must return the ` +
        `current state for any unknown actions, unless it is undefined, ` +
        `in which case you must return the initial state, regardless of the ` +
        `action type. The initial state may not be undefined, but can be null.`
      )
    }
  })
}
三、分析combineReducers函數(shù)的返回值:

函數(shù)combination是一個標準的reducer函數(shù),有初始化的state參數(shù),和一個攜帶了actionType和數(shù)據(jù)的action對象。

function combination(state = {}, action) {
    //如果有非法的reducer,就直接報錯嘍
    if (shapeAssertionError) {
      throw shapeAssertionError
    }

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

    let hasChanged = false
    //定義新的nextState
    const nextState = {}
    // 1,遍歷reducers對象中的有效key,
    // 2,執(zhí)行該key對應的value函數(shù),即子reducer函數(shù),并得到對應的state對象,即子state
    // 3,將新的子state掛到新的nextState對象上,key不變
    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
      //如果hasChanged為true,那就是true了   后面的判斷是,只要有一次nextStateForKey!== previousStateForKey不同,就說明整個state不同
      hasChanged = hasChanged || nextStateForKey !== previousStateForKey
    }
    //如果state發(fā)生變化了,直接返回新的nextState,否則,還是返回舊的state
    return hasChanged ? nextState : state
  }
}
四、總結:

combineReducers函數(shù)其實就實現(xiàn)一個功能:將一個復雜的父reducer函數(shù),根據(jù)state狀態(tài)對應的key,拆分成幾個子reducer;每個子reducer返回一個子state。多層嵌套的reducer樹,可以對應組成一個多層嵌套的state狀態(tài)樹。

完整解析請參考我的github:https://github.com/abczhijia/...,如果對您有幫助,歡迎star,有任何問題也請指正。

文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://systransis.cn/yun/89067.html

相關文章

  • 你想要的——redux源碼分析

    摘要:大家好,今天給大家?guī)淼氖堑脑创a分析首先是的地址點我接下來我們看看在項目中的簡單使用,一般我們都從最簡單的開始入手哈備注例子中結合的是進行使用,當然不僅僅能結合,還能結合市面上其他大多數(shù)的框架,這也是它比較流弊的地方首先是創(chuàng)建一個首先我們 大家好,今天給大家?guī)淼氖莚edux(v3.6.0)的源碼分析~ 首先是redux的github地址 點我 接下來我們看看redux在項目中的簡單使...

    enrecul101 評論0 收藏0
  • 解密Redux: 從源碼開始

    摘要:接下來筆者就從源碼中探尋是如何實現(xiàn)的。其實很簡單,可以簡單理解為一個約束了特定規(guī)則并且包括了一些特殊概念的的發(fā)布訂閱器。新舊中存在的任何都將收到先前的狀態(tài)。這有效地使用來自舊狀態(tài)樹的任何相關數(shù)據(jù)填充新狀態(tài)樹。 Redux是當今比較流行的狀態(tài)管理庫,它不依賴于任何的框架,并且配合著react-redux的使用,Redux在很多公司的React項目中起到了舉足輕重的作用。接下來筆者就從源碼...

    remcarpediem 評論0 收藏0
  • Redux 源碼拾遺

    摘要:循環(huán)還沒有結束,其中的某個對進行了添加或者刪除,都會影響到此次循環(huán)的進行,帶來不可預期的錯誤。 首先來一段 redux 結合 中間件 thunk、logger 的使用demo 了解一下應該如何使用 const redux = require(redux) const { createStore, combineReducers, bindActionCreators, ...

    CloudwiseAPM 評論0 收藏0
  • Redux 源碼拾遺

    摘要:循環(huán)還沒有結束,其中的某個對進行了添加或者刪除,都會影響到此次循環(huán)的進行,帶來不可預期的錯誤。 首先來一段 redux 結合 中間件 thunk、logger 的使用demo 了解一下應該如何使用 const redux = require(redux) const { createStore, combineReducers, bindActionCreators, ...

    zhangfaliang 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<