Home > Software engineering >  How to return the result of " axios' POST request " from reducer function in react
How to return the result of " axios' POST request " from reducer function in react

Time:11-26

I am sending data (string) from the dispatch function and want to return the object which was returned as a result of the POST request, but since axios works asynchronously, the return statement is executed before the POST request's result. Plz help

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

CodePudding user response:

The reducer function should not be making the call itself. They should be pure functions with no side-effects. Calling an API via axios is considered as being a side-effect.

A better option would be to encapsulate your logic in a function (or extracted to a hook), that then dispatches an action with the result of the axios call.

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}});
  });
}

Now your reducer function can handle the QUESTION_VOTES_CHANGED action:

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

  return state;
}

This will work with an state that looks something like:

{
  "Question1": 1,
  "Question2": 8
}

CodePudding user response:

Unfortunately, reducer can not return any value to the code it's called from. As told in this piece of documentation:

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

On the other hand, you can update your store inside the reducer and get new values by subscribing your client code to updates.

Here is a pretty good illustration of the overall flow.

  • Related