combineReducers(reducers)
隨著應(yīng)用變得復(fù)雜,需要對 reducer 函數(shù) 進(jìn)行拆分,拆分后的每一塊獨(dú)立負(fù)責(zé)管理 state 的一部分。
combineReducers
輔助函數(shù)的作用是,把一個由多個不同 reducer 函數(shù)作為 value 的 object,合并成一個最終的 reducer 函數(shù),然后就可以對這個 reducer 調(diào)用 createStore
。
合并后的 reducer 可以調(diào)用各個子 reducer,并把它們的結(jié)果合并成一個 state 對象。state 對象的結(jié)構(gòu)由傳入的多個 reducer 的 key 決定。
Flux 用戶使用須知
本函數(shù)可以幫助你組織多個 reducer,使它們分別管理自身相關(guān)聯(lián)的 state。類似于 Flux 中的多個 store 分別管理不同的 state。在 Redux 中,只有一個 store,但是
combineReducers
讓你擁有多個 reducer,同時保持各自負(fù)責(zé)邏輯塊的獨(dú)立性。
reducers
(Object): 一個對象,它的值(value) 對應(yīng)不同的 reducer 函數(shù),這些 reducer 函數(shù)后面會被合并成一個。下面會介紹傳入 reducer 函數(shù)需要滿足的規(guī)則。之前的文檔曾建議使用 ES6 的
import * as reducers
語法來獲得 reducer 對象。這一點(diǎn)造成了很多疑問,因此現(xiàn)在建議在reducers/index.js
里使用combineReducers()
來對外輸出一個 reducer。下面有示例說明。
(Function): 一個調(diào)用 reducers
對象里所有 reducer 的 reducer,并且構(gòu)造一個與 reducers
對象結(jié)構(gòu)相同的 state 對象。
本函數(shù)設(shè)計(jì)的時候有點(diǎn)偏主觀,就是為了避免新手犯一些常見錯誤。也因些我們故意設(shè)定一些規(guī)則,但如果你自己手動編寫根 redcuer 時并不需要遵守這些規(guī)則。
每個傳入 combineReducers
的 reducer 都需滿足以下規(guī)則:
所有未匹配到的 action,必須把它接收到的第一個參數(shù)也就是那個 state
原封不動返回。
永遠(yuǎn)不能返回 undefined
。當(dāng)過早 return
時非常容易犯這個錯誤,為了避免錯誤擴(kuò)散,遇到這種情況時 combineReducers
會拋異常。
如果傳入的 state
就是 undefined
,一定要返回對應(yīng) reducer 的初始 state。根據(jù)上一條規(guī)則,初始 state 禁止使用 undefined
。使用 ES6 的默認(rèn)參數(shù)值語法來設(shè)置初始 state 很容易,但你也可以手動檢查第一個參數(shù)是否為 undefined
。
雖然 combineReducers
自動幫你檢查 reducer 是否符合以上規(guī)則,但你也應(yīng)該牢記,并盡量遵守。
reducers/todos.js
export default function todos(state = [], action) {
switch (action.type) {
case 'ADD_TODO':
return state.concat([action.text]);
default:
return state;
}
}
reducers/counter.js
export default function counter(state = 0, action) {
switch (action.type) {
case 'INCREMENT':
return state + 1;
case 'DECREMENT':
return state - 1;
default:
return state;
}
}
reducers/index.js
import { combineReducers } from 'redux';
import todos from './todos';
import counter from './counter';
export default combineReducers({
todos,
counter
});
App.js
import { createStore } from 'redux';
import reducer from './reducers/index';
let store = createStore(reducer);
console.log(store.getState());
// {
// counter: 0,
// todos: []
// }
store.dispatch({
type: 'ADD_TODO',
text: 'Use Redux'
});
console.log(store.getState());
// {
// counter: 0,
// todos: ['Use Redux']
// }
本方法只是起輔助作用!你可以自行實(shí)現(xiàn)不同功能的 combineReducers
,甚至像實(shí)現(xiàn)其它函數(shù)一樣,明確地寫一個根 reducer 函數(shù),用它把子 reducer 手動組裝成 state 對象。
在 reducer 層級的任何一級都可以調(diào)用 combineReducers
。并不是一定要在最外層。實(shí)際上,你可以把一些復(fù)雜的子 reducer 拆分成單獨(dú)的孫子級 reducer,甚至更多層。
更多建議: