Redux FAQ: レデューサー
目次
レデューサー
2つのレデューサー間で状態を共有するにはどうすればよいですか? combineReducers
を使用する必要がありますか?
Reduxストアの推奨構造は、状態オブジェクトをキーで複数の「スライス」または「ドメイン」に分割し、各データスライスを管理するための個別のレデューサー関数を用意することです。これは、標準のFluxパターンが複数の独立したストアを持つ方法と似ており、Reduxはこのパターンを容易にするために combineReducers
ユーティリティ関数を提供しています。ただし、combineReducers
は必須ではないことに注意することが重要です。これは、データにプレーンなJavaScriptオブジェクトを使用し、状態スライスごとに単一のレデューサー関数を持つという一般的なユースケースのためのユーティリティ関数にすぎません。
多くのユーザーは、後で2つのレデューサー間でデータを共有しようとして、combineReducers
ではそれができないことに気づきます。使用できるアプローチはいくつかあります。
- レデューサーが状態の別のスライスからのデータを知る必要がある場合、単一のレデューサーがより多くのデータを処理するように状態ツリーの形状を再編成する必要がある場合があります。
- これらのアクションの一部を処理するために、カスタム関数を記述する必要がある場合があります。これには、
combineReducers
を独自のカスタムトップレベルレデューサー関数に置き換える必要がある場合があります。また、reduce-reducers などのユーティリティを使用して、combineReducers
を実行してほとんどのアクションを処理し、状態スライスをまたがる特定のアクションに対してより特殊なレデューサーを実行することもできます。 - 非同期ロジックを持つミドルウェア (例: redux-thunk) は、
getState()
を介して状態全体にアクセスできます。アクションクリエーターは、状態から追加データを取得してアクションに配置できるため、各レデューサーは独自の状態スライスを更新するのに十分な情報を持つことができます。
一般に、レデューサーは単なる関数であることを忘れないでください。好きな方法で整理したり、細分化したりできます。また、より小さく再利用可能な関数(「レデューサー合成」)に分割することをお勧めします。その際、子レデューサーが次の状態を計算するために追加のデータが必要な場合は、親レデューサーからカスタムの3番目の引数を渡すことができます。重要なのは、それらがまとめてレデューサーの基本ルール (state, action) => newState
に従い、状態を直接変更するのではなく、不変的に更新することです。
詳細情報
ドキュメンテーション
ディスカッション
- #601: アクションが複数のレデューサーに関連する場合のcombineReducersに関する懸念
- #1400: トップレベルの状態オブジェクトをブランチレデューサーに渡すのはアンチパターンですか?
- Stack Overflow: 複合レデューサーを使用する場合に状態の他の部分にアクセスするには?
- Stack Overflow: redux combineReducersでサブツリー全体を削減する
- Reduxレデューサー間での状態の共有
アクションを処理するために`switch`文を使用する必要がありますか?
いいえ。レデューサーでアクションに応答するために、好きなアプローチを使用できます。 switch
文が最も一般的なアプローチですが、if
文、関数のルックアップテーブルを使用したり、これを抽象化する関数を作成したりしても問題ありません。実際、Reduxではアクションオブジェクトに type
フィールドが含まれている必要がありますが、レデューサーロジックはアクションを処理するためにそれに依存する必要はありません。とはいえ、標準的なアプローチは間違いなく`type`に基づくswitch文またはルックアップテーブルを使用することです。
詳細情報
ドキュメンテーション
ディスカッション