2017-01-23 9 views
1

私はページを使ったアンケートであるreduxアプリケーションを持っています。ページを変更するには、NAVIGATION_NEXT_PAGEアクションが必要です。次に、Reducersはストア内の新しいページの作成を処理します。私は質問の回答を設定したり、ページをナビゲートする他のアクションがあります。 NAVIGATION_NEXT_PAGEで表示されるすべての新しいページには、ページが最初に表示されたときや質問に答えられたときに実行されるユーザー定義アクションのリストがあります。他のアクションの結果からアクションをキューに入れる方法

私の問題は、アクションロジックをコンポーネントから切り離しながら、新しいページが表示されるたびに再帰的にアクションをディスパッチすることです。アクションがスキップするように要求した場合は、ページを表示したくないので、私はPageContainerにアクションをディスパッチしたくありません。

これは私の現在のソリューションです:

const actionMiddleware = (store) => (next) => (action) => { 
    // Execute post answer actions on the current page. 
    switch (action.type) { 
     case types.NAVIGATION_NEXT_PAGE: 
      for (let postAnswerAction of store.getState().postAnswerActions); 
       next(store.dispatch(actionFromPageAction(postAnswerAction))) 
      break; 
    } 
    // Evaluate the action. 
    let result = next(action); 
    // Execute the preload actions of the new page. 
    switch (action.type) { 
     case types.NAVIGATION_NEXT_PAGE: 
      for (let preLoadAction of store.getState().preLoadActions); 
       next(store.dispatch(actionFromPageAction(preLoadAction))) 
      break; 
    } 
    return result; 
}; 

しかし、時には、私のUIを更新しない反応として、それは奇妙な行動を紹介しています。多分、私のミドルウェアが反応を遅らせるのでしょうか?

私は正しい軌道に乗っています。私のミドルウェアからアクションをディスパッチする正しい方法は何ですか?

+0

他のライブラリをチェックアウトするのではない場合、[redux-observable](https://github.com/redux-observable/redux-observable)はrxjs 'Observables'の力でこれ以上のことをします。これは本質的に、あなたのアクションを1つの 'Observable'ストリームにラップし、あなたはそれらをepicsと呼ばれる関数で変換することができます。また、ミドルウェアを追加する必要はありません。ミドルウェアは、はるかに一般的なレベルで動作するはずです。 –

+0

私は非同期機能は必要ないので、RxJSに依存しない代替手段がありますか?依存関係を限定するため。 –

+0

以下の回答を追加しました。慎重に読んでください。店内での行動を維持することは、実際には良い習慣のようには見えません。 –

答えて

1

あなたは手作りの解決策を作ることができますが、これはお勧めできません。以下の例では、特定のアクションとストアに基づいて新しいアクションを返す機能を持つ一連の機能を組み合わせています。私はいくつかのコードは、あなたが(彼らは同様に私の例では損なわれていない)掲載例で匂いを参照しかし

const actionTransformerMiddleware = (...transformers) => store => next => inAction => { 
    transformers.map(transformer => transformer(inAction, store)) 
    .filter(output => !!output) // checking if non null undefined or empty array 
    .forEach(actions => 
     // Here alternatively you could store.dispatch these, then the new actions 
     // go through the same action transformers, but you won't be able 
     // to return an identical action, since that would cause an endless cycle. 
     (Array.isArray(actions) ? actions : [actions]).forEach(action => next(action)) 
    ) 
} 

const whateverActionTransformer = (action, store) => { 
    const {postAnswerActions, preLoadActions} = store.getState() 
    switch (action.type) { 
    case types.NAVIGATION_NEXT_PAGE: 
     return (postAnswerActions || []).concat(preLoadAction || []) 
    } 
} 

const myActionMiddleware = actionTransformerMiddleware( 
    whateverActionTransformer, 
    // here more of these could come... but maybe they shouldn't? 
) 

(私はそれをテストしていませんが、理論的にはそれがうまくいくかもしれません)。

なぜストアにアクションを保存していますか?なぜあなたはそれらを個別に派遣していませんか?それが実現不可能な場合、これらのアクションが実行するペイロードだけでアクションをディスパッチし、サンクプレフォームを実行してすべての結果を結合し、単一の出力を与えるのはなぜですか?

+0

あなたが正しいです、店の行動はコードのにおいです。私のページアクションのモデルは還元的なアクションではありませんが。私は例を単純化するためにそれを書いた。ユーザー定義のアクションを調査の複数のページで実行する必要がある場所をどこかに格納する必要があるため、店舗でそれらを必要とします。私はサンプルを編集しました。混乱して申し訳ありません。あなたの例を試してみましょう。私はあなたの答えを後で受け入れます。ありがとうございました! –

+0

私はこのことからも、ミドルウェアと「次のもの」がどのように動作するかは分かりませんでしたが、心配する必要はありません)が、あなたの状態に保存するものの名​​前を、アクションと呼ばれないものに変更するようお勧めします。私は保証することができます、あなたのコードを読む次の開発者にとっては、少なくとも軽く混乱するでしょう。 –

+0

良いアイデア、私はそれが会社の他のプロジェクトで使われていた用語ではなかったと思います。 –

関連する問題