亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

自定義 Redux 中的 combineReducers

szysky / 3403人閱讀

摘要:簡(jiǎn)介中的能讓我們很方便地把多個(gè)組合起來(lái),成為一個(gè)新的。正如官方文檔所說(shuō)只是方便我們使用而已,我們可以自定義一個(gè)完全不同的來(lái)滿足我們特殊的需求。這個(gè)原則看著是很美好的,但在實(shí)際使用中還是會(huì)有一些例外的情況。

簡(jiǎn)介

Redux 中的 combineReducers 能讓我們很方便地把多個(gè) reducers 組合起來(lái),成為一個(gè)新的 reducer。
然而,隨著我們的應(yīng)用變得越來(lái)越復(fù)雜,combineReducers 有可能不能滿足我們的需求。
正如 Redux 官方文檔所說(shuō):

This helper is just a convenience! You can write your own combineReducers that works differently, or even assemble the state object from the child reducers manually and write a root reducing function explicitly, like you would write any other function.

combineReducers 只是方便我們使用而已,我們可以自定義一個(gè)完全不同的 combineReducers 來(lái)滿足我們特殊的需求。

原理

我們先回憶一下 reducer 的寫(xiě)法:

const reducer = (oldState, action) => newState;

reducer 是一個(gè)普通的函數(shù),接受兩個(gè)參數(shù):oldStateaction,然后返回一個(gè) newState
為了把多個(gè) reducers 組合起來(lái),我們通常會(huì)用 Redux 自帶的 combineReducers 來(lái)實(shí)現(xiàn):

const rootReducer = combineReducers({
  key1: key1Reducer,
  key2: key2Reducer
});

先留意一下我們傳了什么給 combineReducers:

{
  key1: function(state.key1, action) { /*...*/ },
  key2: function(state.key2, action) { /*...*/ },
}

好了,讓我們先來(lái)想一想,經(jīng)過(guò) combineReducers 的處理之后,我們得到了什么呢?
不用想了,很顯然我們得到了一個(gè)新的 reducer。
那這個(gè)新的 reducer 又長(zhǎng)什么樣呢?

const rootReducer = (oldState, action) => newState;

你應(yīng)該不會(huì)驚訝,因?yàn)樗?reducer 都長(zhǎng)這個(gè)樣子,即使它是已經(jīng)被組合過(guò)的 reducer,它也是長(zhǎng)這個(gè)樣子。
現(xiàn)在你應(yīng)該猜到 combineReducers 做了什么了吧?其實(shí)它最基本形態(tài)是這樣子的:

function combineReducers(reducers) {
  return function (state, action) { /*...*/ };
}

它接受 reducers 作為參數(shù),然后返回一個(gè)標(biāo)準(zhǔn)的 reducer 函數(shù)。

注意:
其實(shí)到了這一步,我們就可以自定義 combineReducers 了,我們完全可以寫(xiě)一個(gè)類似的函數(shù),然后在里面寫(xiě)各種 switch...case 語(yǔ)句來(lái)達(dá)到自定義的目的。
但我覺(jué)得我們還是先看看 Redux 自帶的 combineReducers 做了什么比較好,因?yàn)槲覀冏远x的 combineReducers 很有可能需要原來(lái)的功能。

還記得我剛才叫你留意的地方嗎?沒(méi)錯(cuò),就是下面這個(gè):

// reducers
{
  key1: function(state.key1, action) { /*...*/ },
  key2: function(state.key2, action) { /*...*/ }
}

我們來(lái)回想一下 store.dispatch(action) 的過(guò)程:當(dāng)一個(gè) action 觸發(fā)的時(shí)候,所有 reducers 都應(yīng)該響應(yīng)這個(gè) action,做出相應(yīng)的改變,最后返回一個(gè)新的 store。
對(duì)著上面這個(gè)結(jié)構(gòu),我們其實(shí)很容易就能寫(xiě)出這樣的效果,還能加上一些其他的處理:

function reCombineReducers(reducers) {
  return function (state, action) {
    switch (action.type) {
      case SP_ACTION:
        return Object.assign({}, state, { /* do something */ });
      default:
        return Object.keys(reducers)
                    .map(k => ({ [k]: reducers[k](state[k], action) }))
                    .reduce((prev, next) => Object.assign({}, prev, next));
    }
  }
}

上面的例子模擬了原來(lái) combineReducers 的功能,還對(duì) SP_ACTION 進(jìn)行了特殊的處理,很簡(jiǎn)單吧!

然而,上面的例子雖然模擬了 combineReducers 的功能,但失去了 combineReducers 的檢查對(duì)象變化的功能,因?yàn)楝F(xiàn)在的 default block 中會(huì)返回一個(gè)全新的對(duì)象。
有沒(méi)有方法可以既保留 combineReducers 的全部功能,又能擴(kuò)展它呢?
其實(shí)很簡(jiǎn)單,我們只要利用 combineReducers 返回的函數(shù)就可以了!
(感謝 liximomo 指出上面例子中的缺陷)

function reCombineReducers(reducers) {
  let fn = combineReducers(reducers);
  return function (state, action) {
    switch (action.type) {
      case SP_ACTION:
        return Object.assign({}, state, { /* do something */ });
      default:
        return fn(state, action);
    }
  }
}
實(shí)例

按照 Redux 的原則,不同的 reducer 應(yīng)該相互獨(dú)立的,它們之間不應(yīng)該有任何依賴。
這個(gè)原則看著是很美好的,但在實(shí)際使用中還是會(huì)有一些例外的情況。
一個(gè)很簡(jiǎn)單的例子,也是我遇到過(guò)的例子,就是實(shí)現(xiàn)一個(gè)簡(jiǎn)單的表格 (其實(shí)我的情況復(fù)雜的多,需要實(shí)現(xiàn)類似 Excel 那樣的操作,同時(shí)支持其他額外的功能)。
我們先來(lái)設(shè)計(jì)一下 state:

// state
{
  rows: { ... },
  cells: { ... },
  data: { ... }
}

rows, cells, data 都會(huì)響應(yīng)一些特定的 action (如 CHANGE_ROW_PROPS, CHANGE_CELL_PROPS, CHANGE_DATA),做出相應(yīng)的改變,這些都是我們所期望的。
然而,當(dāng)出現(xiàn)一些特殊的 action (如 GET_TABLE_SUCCESS,表示成功從服務(wù)端獲取數(shù)據(jù)) 的時(shí)候,災(zāi)難就出現(xiàn)了:
所有的 reducer 都需要監(jiān)聽(tīng) GET_TABLE_SUCCESS 這個(gè) action,這意味著如果我們有 n 個(gè) reducer 的話,我們就需要修改 n 個(gè)文件!
當(dāng)我再加上 UPDATE_TABLE_SUCCESS,REMOVE_TABLE_SUCCESS 之類的 action 時(shí),我要再修改 n 個(gè)文件!
這不合理啊,為什么我加一個(gè)簡(jiǎn)單的功能,需要修改這么多文件,最重要的是,這些修改都是非常類似!

這時(shí)候,我們就需要自定義 combineReducers 來(lái)解決我們的需求拉:

function reCombineReducers(reducers) {
  let fn = combineReducers(reducers);
  return function (state, action) {
    switch (action.type) {
      case GET_TABLE_SUCCESS:
      case UPDATE_TABLE_SUCCESS:
        return Object.assign({}, state, action.payload.table);
      case REMOVE_TABLE_SUCCESS:
        return initState;
      default:
        return fn(state, action);
    }
  }
}

const table = reCombineReducers({
  sections,
  suites,
  rows,
  cells,
  toys,
  data,
  logics
})

怎么樣,是不是比修改多個(gè)文件舒服很多?

(完)

出處

http://scarletsky.github.io/2...

參考資料

http://redux.js.org/docs/api/...
https://github.com/reactjs/re...

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/80096.html

相關(guān)文章

  • React原理及其工作流程

    摘要:再次將子返回的單個(gè)進(jìn)行合并成一個(gè)新的完整的。此時(shí)發(fā)生了變化。如果不相同則調(diào)用觸發(fā)組件的更新,傳入組件,觸發(fā)組件的更新,此時(shí)組件獲得新的,的一次流程結(jié)束。 react-redux提供了connect和provider兩個(gè)好方式,provider將組件和redux關(guān)聯(lián)起來(lái),將store傳給組件,組件通過(guò)dispatch發(fā)出action,store根據(jù)action的type屬性,調(diào)用對(duì)應(yīng)的r...

    levy9527 評(píng)論0 收藏0
  • 深入淺出redux學(xué)習(xí)(-)

    摘要:只要輸入的值不變,每次輸出都是一樣的值。指定位置元素運(yùn)算操作如可用以下方式代替主要是生成中最核心的對(duì)象。描述發(fā)生了什么,是響應(yīng)并對(duì)進(jìn)行更新。生成的對(duì)象包含個(gè)方法,分別為,和。按照約定,具有字段來(lái)表示它的類型。 前言: 一開(kāi)始接觸redux的時(shí)候最令我記住的一句話是:You Might Not Need Redux(那我還寫(xiě)這篇文章干嘛?手動(dòng)滑稽) 回歸正題,本文主要是圍繞redux...

    xietao3 評(píng)論0 收藏0
  • React項(xiàng)目實(shí)戰(zhàn):react-redux-router基本原理

    摘要:組件將元素作為結(jié)果返回。是把數(shù)據(jù)從項(xiàng)目傳到的有效載荷。有以下職責(zé)維持應(yīng)用的提供方法獲取提供方法更新通過(guò)注冊(cè)監(jiān)聽(tīng)器通過(guò)返回的函數(shù)注銷(xiāo)監(jiān)聽(tīng)器。系列目錄前端大統(tǒng)一時(shí)代即將來(lái)臨項(xiàng)目實(shí)戰(zhàn)環(huán)境搭建項(xiàng)目實(shí)戰(zhàn)基本原理項(xiàng)目實(shí)戰(zhàn)登錄頁(yè)面編輯中 React相關(guān) React 是一個(gè)采用聲明式,高效而且靈活的用來(lái)構(gòu)建用戶界面的框架。 JSX 本質(zhì)上來(lái)講,JSX 只是為React.createElement(co...

    MorePainMoreGain 評(píng)論0 收藏0
  • React項(xiàng)目實(shí)戰(zhàn):react-redux-router基本原理

    摘要:組件將元素作為結(jié)果返回。是把數(shù)據(jù)從項(xiàng)目傳到的有效載荷。有以下職責(zé)維持應(yīng)用的提供方法獲取提供方法更新通過(guò)注冊(cè)監(jiān)聽(tīng)器通過(guò)返回的函數(shù)注銷(xiāo)監(jiān)聽(tīng)器。系列目錄前端大統(tǒng)一時(shí)代即將來(lái)臨項(xiàng)目實(shí)戰(zhàn)環(huán)境搭建項(xiàng)目實(shí)戰(zhàn)基本原理項(xiàng)目實(shí)戰(zhàn)登錄頁(yè)面編輯中 React相關(guān) React 是一個(gè)采用聲明式,高效而且靈活的用來(lái)構(gòu)建用戶界面的框架。 JSX 本質(zhì)上來(lái)講,JSX 只是為React.createElement(co...

    Doyle 評(píng)論0 收藏0
  • Redux 初見(jiàn)

    摘要:函數(shù)的作用是,返回一個(gè)最終的函數(shù),做的事情是得到一個(gè)由多個(gè)不同函數(shù)作為可以自定義的對(duì)象。把數(shù)據(jù)放到一個(gè)對(duì)象列表中,每個(gè)數(shù)據(jù)用作為主鍵。不同類型的對(duì)象通過(guò)引用數(shù)據(jù),這樣數(shù)據(jù)發(fā)生改變的時(shí)候,只需要修改一處地方,減少數(shù)據(jù)冗余或者混用。 Redux初見(jiàn) 本文記錄的是自己對(duì)redux的學(xué)習(xí)和理解,希望可以簡(jiǎn)潔易懂,入門(mén)redux,一步步的走進(jìn)redux! Redux是什么 Redux是Java...

    trigkit4 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<