2016-08-19 6 views
1

私はReduxのは比較的新しいんだ、と私は次のような状況があります。Redux:どのように2つのレデューサーを特定の順序で同じアクションに対応させることができますか?

  1. マイアプリは応答が戻ってくると{type: 'RECEIVE_FIRST_MESSAGE', message}をディスパッチサーバーから
  2. の最初の「メッセージ」オブジェクトをフェッチするためにAJAX要求を行うと
  3. マイMessageReducerハンドルによってRECEIVE_FIRST_MESSAGE

    A)state.messages

    action.messageを追加します私は2番目のフェッチ:

    B)次のメッセージを取得するために別のAJAX呼び出しを行う(action.message.hasNextMessage場合)

  4. SessionReducerも一つだけ問題がありますaction.message.sessionId

state.session.idにを追加することにより、 RECEIVE_FIRST_MESSAGEを扱いますメッセージ、私は最初のメッセージから得た sessionIdを使用する必要があります。しかし MessageReducerSessionReducerより前に実行されているため、セッションIDは、 MessageReducerが2番目のAJAX要求を作成しようとした時点の状態にありません。

タイムアウトを使用してMessageReducerが1ms後に2回目のリクエストを作成しないようにすることで解決できましたが、ハック/アンチパターンのように感じます。

TLDR

私が持っている:

  • stateの2つの部分のためのデータ(二つの異なる減速によって処理)しているアクション
  • 私はAJAX呼び出しをトリガーします応答、減速機から
  • 減速材Bからの応答でいくつかの状態(state.session.id)を追加したいB

減速機Aが減速機AがAJAX呼び出しを行う前に、どのように減速機Bが状態を追加するようにすることができますか?(Dan Abramovが泣かないように)

+1

redux thunksやsagasのようなものをお使いですか?あなたが処理しているメッセージに既に入っている場合、なぜそれをセッションから取得する必要がありますか?しかし、あなたは減速機でAjaxコールをしていますか? –

+0

はい私はサンクを使用しています。なぜ私は国家からIDを取得するのだろう...私はそれについて考えていると思う今、私はありません。私はちょうど考えていた "1つのアクションは、状態にIDを追加する別のアクションは、状態からIDを引っ張る"(しかし、あなたが気づいたので)私はすでに私がアクションで必要なすべてを持って、 (まあ、後のリクエストを除き、タイミングの問題はありません)。ありがとう!あなたが "このケースで定義すると、あなたはすでに必要なものすべてを持っている"という効果を出すために何かを入れたいと思うなら、私はそれをうれしく受け入れます。 – machineghost

答えて

5

最初のものが最初です。減速機の内部からAJAXコールをしないでください。これまでhttps://www.youtube.com/watch?v=Q-lv8kyYrqQ

リデューサ関数は、(HTTPリクエストなどの)副作用がなく、純粋であると考えられています。代わりに、あなたの利点にthunksを使用してください。以下は、これを行う方法の例です。

サーバーから最初のメッセージ応答を戻したら、RECEIVE_FIRST_MESSAGEアクションをディスパッチします。状態原子を同期して更新します。完了したら、メッセージに次のメッセージがあるかどうかを確認できます。そうであれば、新しい非同期アクションをディスパッチして次のメッセージを取得します。その非同期アクション作成者の中では、以前にディスパッチしたRECEIVE_FIRST_MESSAGEアクションに応答して更新されることが保証されている状態アトムからセッションIDを取得できます。

質問がある場合はお知らせください。

// getFirstMessageFromServer() and getNextMessageFromServer() are thunks and async action creators 
// fetchFirstMessage() and fetchNextMessage() make HTTP requests 

function getFirstMessageFromServer() { 
    return (dispatch, getState) => { 
    return fetchFirstMessage() 
     .then(message => { 
     dispatch({ type: 'RECEIVE_FIRST_MESSAGE', message }); 
     if (message.hasNextMessage) dispatch(getNextMessageFromServer()); 
     return message; 
     }); 
    }; 
} 

function getNextMessageFromServer() { 
    return (dispatch, getState) => { 
    const { id: sessionId } = getState().session.id; 
    return fetchNextMessage(sessionId) 
     .then(nextMessage => { 
     dispatch({ type: 'RECEIVE_NEXT_MESSAGE', message: nextMessage }); 
     return nextMessage; 
     }); 
    }; 
} 


const rootReducer = combineReducers({ 
    session: sessionReducer, 
    messages: messagesReducer 
}); 

const initialMessages = []; 

function messagesReducer(state = initialMessages, action) { 
    switch(action.type) { 
    case 'RECEIVE_FIRST_MESSAGE': 
     return state.concat(action.message); 
    case 'RECEIVE_NEXT_MESSAGE': 
     return state.concat(action.message); 
    default: 
     return state; 
    } 
} 

const initialSession = { id: null }; 

function sessionReducer(state = initialSession, action) { 
    switch(action.type) { 
    case 'RECEIVE_FIRST_MESSAGE': 
     return { 
     ...state, 
     id: action.message.sessionId 
     }; 
    default: 
     return state; 
    } 
} 
+0

それは意味があります:私は分を持っているときに私はリデュース業者からの呼び出しをリファクタリングし、あなたのパターンに従うことを試みます。ありがとう。 – machineghost

関連する問題