Redux-レデューサー

レデューサーはReduxの純粋関数です。純粋関数は予測可能です。Reduxで状態を変更する唯一の方法はレデューサーです。それはあなたが論理と計算を書くことができる唯一の場所です。レデューサー関数は、ディスパッチされているアプリとアクションの以前の状態を受け入れ、次の状態を計算して、新しいオブジェクトを返します。

次のいくつかのことは、レデューサー内で実行しないでください-

  • 関数引数の突然変異
  • API呼び出しとルーティングロジック
  • Math.random()などの非純粋関数の呼び出し

以下はレデューサーの構文です-

(state,action) => newState

アクションクリエーターモジュールで説明した、Webページに製品アイテムのリストを表示する例を続けましょう。そのレデューサーの書き方を以下に見てみましょう。

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;

まず、状態を「initialState」に設定しない場合、Reduxは未定義の状態でreducerを呼び出します。このコード例では、JavaScriptのconcat()関数が「ITEMS_REQUEST_SUCCESS」で使用されています。これは既存の配列を変更しません。代わりに、新しい配列を返します。

このようにして、状態の変化を回避できます。状態に直接書き込むことは絶対にしないでください。'ITEMS_REQUEST'では、受け取ったアクションから状態値を設定する必要があります。

レデューサーでロジックを記述し、論理データベースで分割できることはすでに説明しました。大規模なアプリケーションを処理するときに、レデューサーを分割してルートレデューサーとして組み合わせる方法を見てみましょう。

ユーザーが製品の注文状況にアクセスしてウィッシュリスト情報を表示できるWebページを設計するとします。ロジックを異なるレデューサーファイルに分離し、それらを独立して機能させることができます。ある注文IDとユーザーIDに対応する注文のステータスを取得するためにGET_ORDER_STATUSアクションがディスパッチされたと仮定します。

/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アクションがディスパッチされて、ユーザーそれぞれのユーザーのウィッシュリスト情報を取得するとします。

/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ユーティリティを使用して両方のレデューサーを組み合わせることができます。CombineReducersは、値が異なるレデューサー関数であるオブジェクトを返す関数を生成します。すべてのレデューサーをインデックスレデューサーファイルにインポートし、それぞれの名前を持つオブジェクトとして組み合わせることができます。

/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);