XML DOM 獲取節點值
551
2025-04-03
combineReducers()
隨著應用變得復雜,需要對 reducer 函數 進行拆分,拆分后的每一塊獨立負責管理 state 的一部分。
combineReducers 輔助函數的作用是,把一個由多個不同 reducer 函數作為 value 的
object,合并成一個最終的 reducer 函數,然后就可以對這個 reducer 調用 createStore。
合并后的 reducer 可以調用各個子 reducer,并把它們的結果合并成一個 state 對象。state 對象的結構由傳入的多個 reducer 的 key 決定。
最終,state 對象的結構會是這樣的:
{ reducer1: ... reducer2: ... }
1
2
3
4
通過為傳入對象的 reducer 命名不同來控制 state key 的命名。例如,你可以調用 combineReducers({ todos: myTodosReducer, counter: myCounterReducer }) 將 state 結構變為 { todos, counter }。
通常的做法是命名 reducer,然后 state 再去分割那些信息,因此你可以使用 ES6 的簡寫方法:combineReducers({ counter, todos })。這與 combineReducers({ counter: counter, todos: todos }) 一樣
參數
reducers (Object): 一個對象,它的值(value) 對應不同的 reducer 函數,這些 reducer
函數后面會被合并成一個。下面會介紹傳入 reducer 函數需要滿足的規則。
之前的文檔曾建議使用 ES6 的 import * as reducers 語法來獲得 reducer 對象。這一點造成了很多疑問,
因此現在建議在 reducers/index.js 里使用 combineReducers() 來對外輸出一個 reducer。
下面有示例說明。
返回值
(Function):一個調用 reducers 對象里所有 reducer 的 reducer,并且構造一個與 reducers
對象結構相同的 state 對象。
注意點
本函數設計的時候有點偏主觀,就是為了避免新手犯一些常見錯誤。也因些我們故意設定一些規則,但如果你自己手動編寫根 redcuer 時并不需要遵守這些規則。
每個傳入 combineReducers 的 reducer 都需滿足以下規則:
所有未匹配到的 action,必須把它接收到的第一個參數也就是那個 state 原封不動返回。
永遠不能返回 undefined。當過早 return 時非常容易犯這個錯誤,為了避免錯誤擴散,遇到這種情況時 combineReducers 會拋異常。
如果傳入的 state 就是 undefined,一定要返回對應 reducer 的初始 state。根據上一條規則,初始 state 禁止使用 undefined。使用 ES6 的默認參數值語法來設置初始 state 很容易,但你也可以手動檢查第一個參數是否為 undefined。
雖然 combineReducers 自動幫你檢查 reducer 是否符合以上規則,但你也應該牢記,并盡量遵守。
示例
reducers/todos.js
export default function todos(state = [], action) { switch (action.type) { case 'ADD_TODO': return state.concat([action.text]) default: return state } }
1
2
3
4
5
6
7
8
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 } }
1
2
3
4
5
6
7
8
9
10
reducers/index.js
import { combineReducers } from 'redux' import todos from './todos' import counter from './counter' export default combineReducers({ todos, counter })
1
2
3
4
5
6
7
8
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' ] // }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
本方法只是起輔助作用!你可以自行實現不同功能的 combineReducers,甚至像實現其它函數一樣,明確地寫一個根 reducer 函數,用它把子 reducer 手動組裝成 state 對象。
在 reducer 層級的任何一級都可以調用 combineReducers。并不是一定要在最外層。實際上,你可以把一些復雜的子 reducer 拆分成單獨的孫子級 reducer,甚至更多層。
MapReduce Redux
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。