第一件事是第一件事。切勿在減速器內進行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;
}
}
您是否使用過像redux thunk或sagas這樣的東西?如果它已經在您正在處理的消息中,爲什麼它需要從會話中獲取它?但是:你在減速器中進行Ajax調用? –
是的,我正在使用thunk。至於爲什麼我會從'狀態'中得到身份證......我想現在我想到了,我不知道。我只是在想「一個動作會將ID添加到狀態中,一個單獨的動作會將ID從狀態中拉出來」,但是由於(如您所述),我已經擁有了我在動作中需要的所有內容,並通過'state'是完全不必要的(好吧,除了以後的請求,但那些沒有時間問題)。謝謝!如果你想把一些東西說成「按照定義在這種情況下你已經擁有了你需要的一切」的話,我會很高興地接受它。 – machineghost