2016-08-19 12 views
1

我是比較新的終極版,和我有以下情況:Redux:我如何讓兩個減速器以特定順序響應相同的動作?

  1. 我的應用程序,使一個AJAX請求的響應回來,並調度{type: 'RECEIVE_FIRST_MESSAGE', message}從服務器獲取的第一個「消息」對象
  2. MessageReducer通過處理RECEIVE_FIRST_MESSAGE

    A)加入到action.messagestate.messages

    B)進行另一AJAX調用來獲取下一條消息(如果action.message.hasNextMessage

  3. SessionReducer也處理RECEIVE_FIRST_MESSAGE,加入action.message.sessionIdstate.session.id

這裏只有一個問題:當我取第二消息,我需要使用我從第一條消息獲得的sessionId。但是因爲MessageReducerSessionReducer之前運行,所以會話ID不在MessageReducer嘗試發出第二個AJAX請求時的狀態。

我可以通過使用超時來「解決」這個問題,以確保MessageReducer在1ms之後不會使其成爲第二個請求,但是這感覺像是一種黑客/反模式。

TLDR

當我有:

  • 其對於state(由兩個不同的減速處理)兩個部分組成
  • 我想觸發一個AJAX調用數據的動作反應,從減速機A
  • 我想添加一些狀態(state.session.id)作爲迴應,從減速機B

如何確保減速器B在減速器A使AJAX調用(以不會使丹阿布拉莫夫哭泣的方式)之前添加狀態?

+1

您是否使用過像redux thunk或sagas這樣的東西?如果它已經在您正在處理的消息中,爲什麼它需要從會話中獲取它?但是:你在減速器中進行Ajax調用? –

+0

是的,我正在使用thunk。至於爲什麼我會從'狀態'中得到身份證......我想現在我想到了,我不知道。我只是在想「一個動作會將ID添加到狀態中,一個單獨的動作會將ID從狀態中拉出來」,但是由於(如您所述),我已經擁有了我在動作中需要的所有內容,並通過'state'是完全不必要的(好吧,除了以後的請求,但那些沒有時間問題)。謝謝!如果你想把一些東西說成「按照定義在這種情況下你已經擁有了你需要的一切」的話,我會很高興地接受它。 – machineghost

回答

5

第一件事是第一件事。切勿在減速器內進行AJAX調用。永遠。 https://www.youtube.com/watch?v=Q-lv8kyYrqQ

Reducer函數應該是純粹的,沒有任何副作用(如HTTP請求)。相反,使用thunks是有利的。下面是你如何做到這一點的例子。

從服務器獲取第一條消息響應後,您會發送RECEIVE_FIRST_MESSAGE操作。這將同步更新狀態原子。完成後,您可以檢查消息是否有下一條消息。如果確實如此,則派遣新的異步操作以獲取下一條消息。在該異步操作創建器內部,您可以從狀態原子獲取會話標識,該標識保證會根據之前分派的RECEIVE_FIRST_MESSAGE操作進行更新。

讓我知道如果您有任何問題。

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

相關問題