Redux - Reducer



Reducer 是 Redux 中的純函式。純函式是可預測的。Reducer 是改變 Redux 中狀態的唯一方式。它是唯一可以編寫邏輯和計算的地方。Reducer 函式將接收應用程式的先前狀態和正在分發的 action,計算下一個狀態並返回新的物件。

以下幾件事永遠不應該在 reducer 中執行:

  • 更改函式引數
  • API 呼叫和路由邏輯
  • 呼叫非純函式,例如 Math.random()

以下是 reducer 的語法:

(state,action) => newState

讓我們繼續在 action 建立者模組中討論的網頁上顯示產品專案列表的示例。讓我們看看下面如何編寫它的 reducer。

const initialState = {
   isLoading: false,
   items: []
};
const reducer = (state = initialState, action) => {
   switch (action.type) {
      case 'ITEMS_REQUEST':
         return Object.assign({}, state, {
            isLoading: action.payload.isLoading
         })
      case ‘ITEMS_REQUEST_SUCCESS':
         return Object.assign({}, state, {
            items: state.items.concat(action.items),
            isLoading: action.isLoading
         })
      default:
         return state;
   }
}
export default reducer;

首先,如果您沒有將 state 設定為“initialState”,Redux 將使用未定義的 state 呼叫 reducer。在這個程式碼示例中,JavaScript 的 concat() 函式用於“ITEMS_REQUEST_SUCCESS”,它不會更改現有陣列;而是返回一個新陣列。

這樣,您可以避免更改狀態。永遠不要直接寫入狀態。“ITEMS_REQUEST”中,我們必須根據接收到的 action 設定 state 值。

前面已經討論過,我們可以在 reducer 中編寫我們的邏輯,並可以根據邏輯資料進行拆分。讓我們看看在處理大型應用程式時如何拆分 reducer 並將它們組合在一起作為根 reducer。

假設,我們想設計一個網頁,使用者可以在其中訪問產品訂單狀態並檢視願望清單資訊。我們可以將邏輯分離到不同的 reducer 檔案中,並使它們獨立工作。讓我們假設 GET_ORDER_STATUS action 被分發以獲取與某個訂單 ID 和使用者 ID 對應的訂單狀態。

/reducer/orderStatusReducer.js
import { GET_ORDER_STATUS } from ‘../constants/appConstant’;
export default function (state = {} , action) {
   switch(action.type) {
      case GET_ORDER_STATUS:
         return { ...state, orderStatusData: action.payload.orderStatus };
      default:
         return state;
   }
}

類似地,假設 GET_WISHLIST_ITEMS action 被分發以獲取使用者的願望清單資訊。

/reducer/getWishlistDataReducer.js
import { GET_WISHLIST_ITEMS } from ‘../constants/appConstant’;
export default function (state = {}, action) {
   switch(action.type) {
      case GET_WISHLIST_ITEMS:
         return { ...state, wishlistData: action.payload.wishlistData };
      default:
         return state;
   }
}

現在,我們可以使用 Redux combineReducers 實用程式組合這兩個 reducer。combineReducers 生成一個函式,該函式返回一個物件,其值是不同的 reducer 函式。您可以將所有 reducer 匯入 index reducer 檔案,並將它們組合在一起作為一個物件,並帶有各自的名稱。

/reducer/index.js
import { combineReducers } from ‘redux’;
import OrderStatusReducer from ‘./orderStatusReducer’;
import GetWishlistDataReducer from ‘./getWishlistDataReducer’;

const rootReducer = combineReducers ({
   orderStatusReducer: OrderStatusReducer,
   getWishlistDataReducer: GetWishlistDataReducer
});
export default rootReducer;

現在,您可以將此 rootReducer 傳遞給 createStore 方法,如下所示:

const store = createStore(rootReducer);
廣告