React useEffect not updating state after async API call [duplicate]

2 weeks ago 12
ARTICLE AD BOX

So what could be happening here is that your state IS updating, but you're seeing the old data. And if you cause that data to change multiple times, you'll notice that your updates seem to be one update behind. If this is what's happening for you, the reason is that React batches updates to state to help with performance. What this means is, if you have some state via useState, and go to update that state AND read the change right after during an effect, you will be reading the stale data, because the state is set to update on the next render, and you're logging the state on the current render, which has the stale data still.

const [myState, setMyState] = useState(0) // Run an effect on mount useEffect(() => { // myState is 0 here // on the current render, we tell React to update the myState state to 1 on the NEXT render setMyState(1); // if we log it here, we'll be logging the stale data, because its not the next render yet. console.log(myState) // will output 0 }, [])

There are a few solutions you can do here. I'd recommend looking up stale closures and looking at the React docs for more information. But one of the simpler solutions to log the changes is to have a second useEffect that logs the myState data, and add myState to the effects dependency array, so that when the data actually changes on the next render, the effect will trigger, which means you'll no longer be seeing stale data.

const [myState, setMyState] = useState(0) useEffect(() => { // pretend we're fetching data on mount here setMyState(1) }, []) // Use effect that listens to changes to myState useEffect(() => { // this is called on the render that the myState data is actually updated. So this will be the most recent data console.log(myState) }, [myState])

I hope I understood your question properly, and that this helps. Definitely recommend checking out the React docs to learn more about these hooks :)

Read Entire Article