gpt4 book ai didi

Redux:如何让两个 reducer 按一定顺序响应相同的操作?

转载 作者:行者123 更新时间:2023-12-03 09:14:48 27 4
gpt4 key购买 nike

我对 Redux 比较陌生,我有以下情况:

  1. 我的应用发出 AJAX 请求以从服务器获取第一个“消息”对象
  2. 响应返回并分派(dispatch){type: 'RECEIVE_FIRST_MESSAGE', message}
  3. 我的 MessageReducer 通过以下方式处理 RECEIVE_FIRST_MESSAGE:

    A) 将 action.message 添加到 state.messages

    B) 进行另一个 AJAX 调用以获取下一条消息(如果 action.message.hasNextMessage)

  4. 我的 SessionReducer 还可以通过将 action.message.sessionId 添加到 state.session.id< 来处理 RECEIVE_FIRST_MESSAGE/

只有一个问题:当我获取第二条消息时,我需要使用从第一条消息中获取的 sessionId。但由于 MessageReducerSessionReducer 之前运行,因此 session ID 不处于 MessageReducer 尝试发出第二个 AJAX 请求时的状态。

我可以通过使用超时来“解决”这个问题,以确保 MessageReducer 直到 1 毫秒后才发出第二个请求,但这感觉像是一种黑客/反模式。

TLDR

当我有:

  • 具有状态两部分数据的操作(由两个不同的 reducer 处理)
  • 我想从 reducer A 触发 AJAX 调用作为响应
  • 我想从 reducer B 添加一些状态 (state.session.id) 作为响应

我怎样才能确保reducer B在reducer A进行AJAX调用之前添加状态(以一种不会让Dan Abramov哭泣的方式)?

最佳答案

首先要做的事情。切勿从 reducer 内部进行 AJAX 调用。曾经。 https://www.youtube.com/watch?v=Q-lv8kyYrqQ

Reducer 函数应该是纯粹的,没有任何副作用(如 HTTP 请求)。相反,使用 thunk 来发挥你的优势。下面是您可以如何执行此操作的示例。

从服务器返回第一条消息响应后,您将调度 RECEIVE_FIRST_MESSAGE 操作。这将同步更新状态原子。完成后,您可以检查该消息是否有下一条消息。如果是,则调度一个新的异步操作以获取下一条消息。在该异步操作创建器中,您可以从状态原子获取 session ID,该状态保证会根据您之前分派(dispatch)的 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:如何让两个 reducer 按一定顺序响应相同的操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39046202/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com