开发者问题收集

如何从 React 中的 Reducer 函数返回“Axios 的 POST 请求”的结果

2021-11-26
1506

我正在从调度函数发送数据(字符串),并希望返回作为 POST 请求结果返回的对象,但由于 axios 是异步工作的,因此返回语句在 POST 请求的结果之前执行。请帮忙

dispatch({ type: "INCREASE_VOTES_QUESTION", payload: loginUser.id })

export default function reducer(state, action) {

    if (action.type === "INCREASE_VOTES_QUESTION") {
        let updatedSingleQuestion
        axios({
            method: "POST",
            url: `http://localhost:5000/questions/${question_id}/votes-update`,
            withCredentials: true,
            data: { action: "increase", id: action.payload },
        }).then((res) => {
            updatedSingleQuestion = res.data
        })
        return updatedSingleQuestion
    }
}
2个回答

Reducer 函数不应自行进行调用。它们应该是没有副作用的纯函数。通过 axios 调用 API 被视为副作用。

更好的选择是将您的逻辑封装在一个函数中(或提取到一个钩子中),然后使用 axios 调用的结果分派一个操作。

function incrementCount(questionId, dispatch) {
  axios({
    method: "POST",
    url: `http://localhost:5000/questions/${questionId}/votes-update`,
    withCredentials: true,
    data: { action: "increase", id: action.payload },
  }).then((res) => {
    dispatch({type: "QUESTION_VOTES_CHANGED", payload: {questionId, votes: res.data}});
  });
}

现在您的 Reducer 函数可以处理 QUESTION_VOTES_CHANGED 操作:

function reducer(state, action) {
  if (action.type === "QUESTION_VOTES_CHANGED") {
    return {
      ...state,
      [action.payload.questionId]: action.payload.votes
    };
  }

  return state;
}

这将适用于类似以下状态:

{
  "Question1": 1,
  "Question2": 8
}
Nick Howard
2021-11-26

不幸的是,reducer 无法向调用它的代码返回任何值。正如 文档中所述:

Reducers are functions that take the current state and an action as arguments, and return a new state result.

另一方面,您可以在 Reducer 中更新您的存储,并通过订阅客户端代码的更新来获取新值。

这里 很好地说明了整体流程。

AndreyProgr
2021-11-26