Redux 進階:拆分 reducer

❓ state 過於龐大怎麼辦

由於 Redux 應用中只有一個 store,所以,當應用的交互愈來愈複雜時,store 一定會變成一個很是龐大的對象。這時,咱們可使用 Redux 提供的 combineReducers() 方法將多個小的 reducer 組合成一個 rootReducer,而每一個小的 reducer 只關心本身負責的 action.type,由於在整個應用中,有些 state 之間是互不關聯的,所以咱們能夠拆分 reducer,不一樣的 reducer 處理不一樣的 action.typegit

假設如今有兩個邏輯:一個計數器和一個 TODO。很明顯這兩個邏輯之間沒有任何的聯繫,所以咱們能夠拆分紅兩個 reducer,而後再組合起來傳給 createStore()github

// 計數器 reducer
function counter(state = 0, action) {
  switch(action.type) {
    case 'INCREMENT':
      return state + 1;
    case 'DECREMENT':
      return state -1;
    default:
      return state;
  }
}

// TODO reducer
function todos(state = [], action) {
  switch(action.type) {
    case 'ADD_TODO':
      return state.concat([action.text]);
    default :
      return state;
  }
}

// 組合成一個 rootReducer
const rootReducer = combineReducers({
  counter,
  todos
});

// 根據 rootReducer 建立 store
const store = createStore(rootReducer)

console.log(store.getState());

結果

https://user-images.githubusercontent.com/22176164/39660627-c5f88b60-5075-11e8-93bc-b7ecc37fd49b.png

能夠看到,store.getState() 中的 key 變成了子 reducer 的函數名,達到了拆分之間沒有聯繫的 state 的目的。而 key 變成了子 reducer 的函數名的緣由是,在組合 reducer 時的寫法:數據庫

// 組合成一個 rootReducer
const rootReducer = combineReducers({
  counter,
  todos
});

這裏傳入給 combineReducers() 方法的是一個對象,這裏使用了 ES6 的語法,即當對象的 keyvalue 同名時,能夠省略 key,上面的寫法至關於:設計模式

const rootReducer = combineReducers({
-  counter,
+  counter: counter,
-  todos
+  todos: todos
});

固然,key 是能夠隨意修改的,只是修改後,對於 state 的 key 也會有所不一樣罷了。須要記住的是 combineReducers() 方法的參數是一個對象,對象的 value 是須要組合的 reducer,對象的key 對應的是 state 中的 key,返回的是一個組合後的 reducer 函數,能夠像普通 reducer 同樣傳給 createStore() 方法建立 store。bash

與 React 結合後結果是這樣的:架構

combinereducers

在 coding 以前

構建一個 Redux 應用以前,咱們應該先搭建好架構,也就是設計模式的那一套東西,在 coding 以前,不妨先停下來思考一下:函數

  • 代碼文件的組織結構工具

    • 按角色組織
    • 按功能組織
  • state 樹的設計性能

    • 一個模塊控制一個 state 節點
    • 避免冗餘數據:作到 state 的範式化,相似 SQL 關係型數據庫。爲解決範式化數據的性能問題,可使用 reselect 這樣的工具提升性能。
    • 樹形結構扁平,避免很深的層次
  • 肯定模塊的邊界:在理想狀況下,咱們應該經過增長代碼就能增長功能,而不是修改現有的代碼。

下面是一個按功能組織的文件結構:spa

todoList/
  action.js            # 定義 action creators
  actionTypes.js       # 定義 action 類型
  index.js             # 把這個功能模塊的文件導入,而後統一導出
  reducer.js           # 定義 reducer 如何處理 action
  views/               # 定義全部 React 組件,包括容器組件和展現組件
    component.js
    container.js
filter/
  action.js
  actionTypes.js
  index.js
  reducer.js
  views/
    component.js
    container.js
相關文章
相關標籤/搜索