0

I'm new in redux. Is it the right way to setState?

How do I setState forYou after fetching data from server?

here is my code:

const initialState={
    forYou: [],
}


function rootReducer(state=initialState, action){
    switch (action.type){
        case 'forYou':
            var url = 'http://127.0.0.1:8000/forYou/'
            fetch(url, {
                method: 'GET',
                headers:{
                    'Content-Type': 'application/json',
                }
            }).then(res=>res.json().then(result=>{
                var forYou = result
                return{
                    ...state,
                    forYou: forYou
                }
            }))
        
        break


        default:
            return state;
    }
}

export default rootReducer

So, what i should change?

Asif Biswas
  • 161
  • 2
  • 9
  • No, your `forYou` case completes and `rootReducer` returns `undefined` before your `fetch` callback runs. Please see [How do I return the response from an aynchronous call](https://stackoverflow.com/q/14220321/438992), which this duplicates. – Dave Newton Jun 03 '21 at 16:38
  • 2
    It is a better practise to move all the fetch calls to a middleware like redux-saga or redux-thunk etc.. From there you can pass details of response via a callback function and then dispatch an action to set state. – Sunny Jun 03 '21 at 16:43

1 Answers1

2

Your reducer must return new state, synchronously, which you're not doing.

The return in your then isn't the return value from your reducer function, it's the return value from the then function, which is ultimately what the fetch call chain will resolve to.

Returning the resolved value (e.g. return fetch(...)) won't work either, because fetch is asynchronous. Its return value is a Promise, not the resolved state.

There are off-the-shelf libraries like saga and thunk to help with this sort of thing, but the basic idea is the same: Move your asynchronous code out to a separate function and have it dispatch state transitions:

// pseudo-code, not an actual implementation
async function forYou () {
  // transition into a loading state; display a spinner or whatever
  dispatch({ type: LOADING, value: true });

  // await the fetch
  const result = await fetch(...);

  // once the fetch completes, dispatch an action with the result
  dispatch({ type: FOR_YOU, value: result })

  // and transition out of the loading state
  dispatch({ type: LOADING, value: false })
}
ray
  • 26,557
  • 5
  • 28
  • 27