Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return state in reducer function during API call

I have a reducer function in which I have to make an API call and then return its result as state. But because of the API call being asynchronous the value of state is not updated.

if (action.type==='CREATE_POST') {
        const x= async () => {
            const res=await  fetch("http://localhost:5000/posts", {
                  method: "post",
                  headers: {
                      'Accept': 'application/json',
                      'Content-Type': 'application/json'
                  },
                  body: JSON.stringify(
                      action.payload
                  )
              })
                  const data= await res.json()
              return data
          }
          return [...state,x]
}

I have also tried this

if (action.type==='CREATE_POST') {
        const x= async () => {
            const res=await  fetch("http://localhost:5000/posts", {
                  method: "post",
                  headers: {
                      'Accept': 'application/json',
                      'Content-Type': 'application/json'
                  },
                  body: JSON.stringify(
                      action.payload
                  )
              })
                  const data= await res.json()
              return data
          }
          return [...state,x().then((data)=>{console.log(data);})]

    }
like image 208
Tarsh Avatar asked Sep 11 '25 15:09

Tarsh


1 Answers

If you are doing an asynchronous task, I suggest you this pattern:

Create 3 files , named:

  1. reducer.js
  2. action.js
  3. effect.js (for asynchronous task)

In reducer

const initialState = {
  loading: false,
  data: [],
  error: ''
}

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case "FETCH_REQUEST":
      return {
        ...state,
        loading: true
      }
    case "FETCH_SUCCESS":
      return {
        loading: false,
        data: action.payload,
        error: ''
      }
    case "FETCH_FAILURE":
      return {
        loading: false,
        data: [],
        error: action.payload
      }
    default: return state
  }
}

export default reducer

In action.js

export const fetchRequest = () => {
    return {
      type: "FETCH_REQUEST"
    }
  }
  
  export const fetchSuccess = data => {
    return {
      type: "FETCH_SUCCESS",
      payload: data
    }
  }
  
  export const fetchFailure = error => {
    return {
      type: "FETCH_FAILURE",
      payload: error
    }
  }

Finally the effect.js

export const fetch = () => {
    return (dispatch) => {
        //Initializing the request
        dispatch(fetchRequest());
        //Calling the api
        api()
            .then((response) => {
                // response is the data
                dispatch(fetchSuccess(response));
            })
            .catch((error) => {
                // error.message is the error message
                dispatch(fetchFailure(error.message));
            });
    };
};
like image 109
Aryaman Kumar Avatar answered Sep 13 '25 03:09

Aryaman Kumar