2016-09-07 5 views
0

レデューサー間の依存関係を管理する方法を知りたい。React Redux - レデューサー間の依存関係を管理する

アクションを実行し、2人のレデューサーがこの操作を「リッスン」しているとしますが、もう1つのレデューサーが実行される前に実行したいとします。

例: 食事の減量剤(食事は成分で構成されています)があります。 すべてのレデューサーは、サーバーからフェッチされたデータを取り出し、その中からキャストオブジェクトを取り出してストアに保存します(たとえば、減量剤がIngredientオブジェクトを作成して新しい状態として返します)。 すべての成分には固有のIDがあります。 Meal ofは、リスト作成者ID(それに含まれる成分)をコンストラクタに取得し、ストアから関連する成分オブジェクトをフェッチし、Mealの属性として追加します。 効率の理由から、すべてのデータ(食材と食事)をサーバーから一枚(1つのGETリクエスト)を取得します。あなたが(ペイロードとしてフェッチされたデータで)FETCH_ALL_DATA_FROM_SERVERを発射するとき - あなたは食材と食事減速の両方が、このアクションに「聞く」にしたい:

  1. を成分の減速は、食材に がフェッチされたことを生の情報を解析する必要がありますサーバーからインベントリオブジェクトをキャストして、 をストアに格納します。
  2. 食事リデューサーは、サーバからキャッチされたMaelオブジェクトに フェッチされた食事の生の情報を解析し、 ストアに保存する必要があります。ここ

しかし、それがトリッキー取得する場所です - 食事の減速がまだ店にはない成分が含まれている食事のオブジェクトを作成しようとした場合(食材の減速がまだ店にそれらをロードしていない)何?

どうすればこの問題を解決できますか?事前に 感謝:)



コード例を更新: フェッチアクションはそのようなことになります。

export function fetchAllDataFromDB() { 
    return dispatch => { 
     axios.get('http://rest.api.url.com') 
      .then(response => { 
       dispatch({ 
        type: FETCH_ALL_DATA_FROM_DB, 
        payload: response.data 
       }) 
      }) 
      .catch(error => { 
       console.log(error) 
      }) 
    } 
} 

を成分の減速は、そのようなものになります

export default function reducer(state={}, action) { 

    switch (action.type) { 
     case FETCH_ALL_DATA_FROM_DB: { 
      // Create the Ingredient objects from the payload 
      // They look like Ingredient(id, name, amount) 

     } 
    } 

    return state 
} 

食事の減速は、次のようになります。

export default function reducer(state={}, action) { 

    switch (action.type) { 
     case FETCH_ALL_DATA_FROM_DB: { 
      // Create the Meal objects from the payload 
      // They look like Meal(id, name, price, ingredients_ids) 
      // It will try to fetch the ingredients (of ingredients_ids) from the store - and fail, because hey are not there yet. 
     } 
    } 

    return state 
} 

問題がある - ingredintsリデューサがストアに関連する成分をロード行われる前に、食事オブジェクトを作成することはできません。私はそれが店から成分のオブジェクトをフェッチしませんので、食事のコンストラクタを変更しましたが、 :私は実際に問題を解決していないが、私がやったワットです


を更新し


ingredients_idsリストに固執します。 また、Mealオブジェクトをストアからフェッチするゲッタを追加しました。 今私は食事が動的で構成されている成分を変更することができますので、それは、この方法より良いかもしれません(私は...したくないということ)。あなたは、私が本当に知りたいのですが、より良い解決策を見つけた場合 それは...しかし 少ない効率的です。助けのための

感謝:)

答えて

1

私はあなたがJavaScriptで非同期に関するトピックについての詳細を検索することができると思います。一般的には

あなたは別の方法を実行する前に完了するために、2つ以上のアクションを待つしたい場合。あなたは、コールバック地獄にPromise.all()、または巣コールバックを使用するか、async.series()ライブラリを使用することができます。戻るReduxのを、あなたがレンダリングする前に、すべてのキューの実行が終了していることを確認することができ(派遣())

はまた、私の推薦は約束の代わりに、非同期ライブラリを学ぶことです。

例の場合:

fetch().then(res => dispatch({type: "I_GET_THE_DATA", payload: res.data})) 

したい場合は、あなたもチェーンフェッチできます。

fetch(mealURL).then(res1 =>{ 
    fetch(ingredientsURL).then(res2 => { 
     var meal_and_ingredients = { 
      meal: res1, 
      ingredients: res2 
     } 


     dispatch({type: "GET_TWO_DATA", payload: meal_and_ingredients}) 
    }) 
}) 
+0

私はPromiseを使用し、コールバックにFETCH_ALL_DATA_FROM_SERVERをディスパッチします。しかし、これで問題は解決しません。FETCH_ALL_DATA_FROM_SERVERをディスパッチすると、両方のレデューサー(食材と食事)が非同期で動作し始めます。私がやりたいことは、何らかの形でそれが完了したら、材料減量剤がLOAD_MEALSアクションを送出するようにすることです。 –

+0

なぜフェッチをデータベースにディスパッチするのか分かりません。反復還元では、ディスパッチはリレンダーに反応を伝えることです。通常、フェッチはクリックまたはディッドマウントの後で、返された値が何であれ処理され、最終的にディスパッチされます。 – vdj4y

+0

これはどう変わりますか?もし "Load Data From Server"ボタンがあれば、それは何か違いがありますか? –