Much like .setState() in class components created by extending React.Component or React.PureComponent, the state update using the updater provided by useState hook is also asynchronous, and will not be reflected immediately.

Also, the main issue here is not just the asynchronous nature but the fact that state values are used by functions based on their current closures, and state updates will reflect in the next re-render by which the existing closures are not affected, but new ones are created. Now in the current state, the values within hooks are obtained by existing closures, and when a re-render happens, the closures are updated based on whether the function is recreated again or not.

Even if you add a setTimeout the function, though the timeout will run after some time by which the re-render would have happened, the setTimeout will still use the value from its previous closure and not the updated one.

setMovies(result);
console.log(movies) // movies here will not be updated

If you want to perform an action on state update, you need to use the useEffect hook, much like using componentDidUpdate in class components since the setter returned by useState doesn't have a callback pattern

useEffect(() => {
    // action on update of movies
}, [movies]);

As far as the syntax to update state is concerned, setMovies(result) will replace the previous movies value in the state with those available from the async request.

However, if you want to merge the response with the previously existing values, you must use the callback syntax of state updation along with the correct use of spread syntax like

setMovies(prevMovies => ([...prevMovies, ...result]));
Answer from Shubham Khatri on Stack Overflow
Top answer
1 of 16
982

Much like .setState() in class components created by extending React.Component or React.PureComponent, the state update using the updater provided by useState hook is also asynchronous, and will not be reflected immediately.

Also, the main issue here is not just the asynchronous nature but the fact that state values are used by functions based on their current closures, and state updates will reflect in the next re-render by which the existing closures are not affected, but new ones are created. Now in the current state, the values within hooks are obtained by existing closures, and when a re-render happens, the closures are updated based on whether the function is recreated again or not.

Even if you add a setTimeout the function, though the timeout will run after some time by which the re-render would have happened, the setTimeout will still use the value from its previous closure and not the updated one.

setMovies(result);
console.log(movies) // movies here will not be updated

If you want to perform an action on state update, you need to use the useEffect hook, much like using componentDidUpdate in class components since the setter returned by useState doesn't have a callback pattern

useEffect(() => {
    // action on update of movies
}, [movies]);

As far as the syntax to update state is concerned, setMovies(result) will replace the previous movies value in the state with those available from the async request.

However, if you want to merge the response with the previously existing values, you must use the callback syntax of state updation along with the correct use of spread syntax like

setMovies(prevMovies => ([...prevMovies, ...result]));
2 of 16
544

Additional details to the previous answer:

While React's setState is asynchronous (both classes and hooks), and it's tempting to use that fact to explain the observed behavior, it is not the reason why it happens.

TLDR: The reason is a closure scope around an immutable const value.


Solutions:

  • read the value in render function (not inside nested functions):

      useEffect(() => { setMovies(result) }, [])
      console.log(movies)
    
  • add the variable into dependencies (and use the react-hooks/exhaustive-deps eslint rule):

      useEffect(() => { setMovies(result) }, [])
      useEffect(() => { console.log(movies) }, [movies])
    
  • use a temporary variable:

      useEffect(() => {
        const newMovies = result
        console.log(newMovies)
        setMovies(newMovies)
      }, [])
    
  • use a mutable reference (if we don't need a state and only want to remember the value - updating a ref doesn't trigger re-render):

      const moviesRef = useRef(initialValue)
      useEffect(() => {
        moviesRef.current = result
        console.log(moviesRef.current)
      }, [])
    

Explanation why it happens:

If async was the only reason, it would be possible to await setState().

However, both props and state are assumed to be unchanging during 1 render.

Treat this.state as if it were immutable.

With hooks, this assumption is enhanced by using constant values with the const keyword:

const [state, setState] = useState('initial')

The value might be different between 2 renders, but remains a constant inside the render itself and inside any closures (functions that live longer even after render is finished, e.g. useEffect, event handlers, inside any Promise or setTimeout).

Consider following fake, but synchronous, React-like implementation:

// sync implementation:

let internalState
let renderAgain

const setState = (updateFn) => {
  internalState = updateFn(internalState)
  renderAgain()
}

const useState = (defaultState) => {
  if (!internalState) {
    internalState = defaultState
  }
  return [internalState, setState]
}

const render = (component, node) => {
  const {html, handleClick} = component()
  node.innerHTML = html
  renderAgain = () => render(component, node)
  return handleClick
}

// test:

const MyComponent = () => {
  const [x, setX] = useState(1)
  console.log('in render:', x) // 
  
  const handleClick = () => {
    setX(current => current + 1)
    console.log('in handler/effect/Promise/setTimeout:', x) //  NOT updated
  }
  
  return {
    html: `<button>${x}</button>`,
    handleClick
  }
}

const triggerClick = render(MyComponent, document.getElementById('root'))
triggerClick()
triggerClick()
triggerClick()
<div id="root"></div>

🌐
Frontend Undefined
frontendundefined.com › posts › react-issues › react-usestate-hook-not-updating-immediately
Is your React useState hook not updating state immediately? Here's how to fix it
January 4, 2023 - React then waits until the function has finished running and re-renders the component by calling the component function with the new value being returned from the useState hook. // What setState really does under the hood // (Not really, but a simplified example) const setCount = (newCount) => { React.stateUpdates.push('count', newCount); } const increment = () => { setCount(count + 1); // Only asks React to re-render the component with this new value. alert('The count is ' + count); // count will retain the old value until the next render. } You can calculate the updated value within the function and use it.
Discussions

UseState hook not getting updated immediately
Can you post the whole component? And please don't use back-ticks because it's conflicting with the JS syntax in your case. If you put four spaces in front of text, it gets formatted as a code block (and it's the only code-block markup syntax that works on all Reddit platforms). If you go to your editor, highlight the code and hit tab twice, you'll get four (or maybe eight) extra spaces. Then copy that code to the post (and then shift+tab twice on your highlighted code to bring it back to how it was). More on reddit.com
🌐 r/reactjs
14
1
February 27, 2022
React useState not updating the variable
I have searched all other occurrences of setStorage but they aren’t the cause as they occur onEvents(like when the message is sent, a new chat etc.) · I have a feature where the data of of the chat messages is copied to the localStorage when the a message is sent or a chat or folder is created ... More on forum.freecodecamp.org
🌐 forum.freecodecamp.org
0
0
April 14, 2023
useState doesn't update component
Here is my code. Clicking the buttons never updates the component. It does change the variable page but the component itself never re renders or shows the current value of the variable. react and r... More on github.com
🌐 github.com
14
February 8, 2019
reactjs - Why useState is not updating immediately after button click? - Stack Overflow
I am trying to update State on click of a button, but when I am doing a console.log it is showing me the old value. Although it was updating the state as I saw in the components tab (react dev tool... More on stackoverflow.com
🌐 stackoverflow.com
🌐
GeeksforGeeks
geeksforgeeks.org › reactjs › how-to-resolve-usestate-set-method-is-not-reflecting-change-immediately
How to Resolve useState Set Method is Not Reflecting Change Immediately? - GeeksforGeeks
July 2, 2024 - The functional update form of setState takes a function as an argument. This function receives the previous state and returns the new state. This ensures that you always have the latest state value, even if multiple updates are queued. Example: In this example, setCount uses a function that receives prevCount and returns prevCount + 1. This guarantees that count is updated correctly, even if other state updates are happening simultaneously. ... import React, { useState } from 'react'; const Counter = () => { const [count, setCount] = useState(0); const incrementCount = () => { setCount(prevCount => prevCount + 1); }; return ( <div> <p>Count: {count}</p> <button onClick={incrementCount}> Increment </button> </div> ); }; export default Counter;
🌐
Refine
refine.dev › home › blog › tutorials › 5 most common usestate mistakes react developers often make
5 Most Common useState Mistakes React Developers Often Make | Refine
May 24, 2024 - However, directly updating the state is a bad practice that could lead to potential bugs when dealing with a live application that several users use. Why? Because contrary to what you may think, React doesn't update the state immediately when the button is clicked, as shown in the example demo.
🌐
LogRocket
blog.logrocket.com › home › why react doesn’t update state immediately
Why React doesn't update state immediately - LogRocket Blog
November 26, 2024 - The callback function in the useEffect Hook runs only when there is a change in any of the state variables listed in its dependency array: Do not use the useEffect Hook unnecessarily, especially in this situation. useEffect is meant for synchronizing your components with external systems, like when you make network and API calls. You can read up more on this on the official docs. The useState Hook in React doesn’t have a built-in callback like setState does.
🌐
Linguine Code
linguinecode.com › home › blog › why react setstate/usestate does not update immediately
Why React setState/useState does not update immediately
December 19, 2020 - React setState and useState are asynchronous actions. React setState and useState only create queues for React core to update the state of React components.
🌐
Daggala
daggala.com › react-state-not-updating-immediately
React state not updating immediately? - Daggala
The reason why the state doesn’t update immediately is because for each render, the state is immutable. You can see that … · const [someState, setSomeState] = useState() …are both constants values !
Find elsewhere
🌐
C# Corner
c-sharpcorner.com › article › how-to-fix-usestate-not-updating-immediately-in-react
How to Fix useState Not Updating Immediately in React
October 3, 2025 - Use useEffect to react to updated state. Use useRef for instant, non-UI values. By following these patterns, you’ll resolve the “useState set method not reflecting change immediately” issue and build more predictable React apps.
🌐
Reddit
reddit.com › r/reactjs › usestate hook not getting updated immediately
r/reactjs on Reddit: UseState hook not getting updated immediately
February 27, 2022 -

Hi,

In my react project , I am using functional components.

After a particular condition is met , I call a function by name "fetchNextList()" that contains an api which requires incremented page number field value every time I call the function . For this I have written following code.

const XyzComponent= () => {

const [searchPageNo, setSearchPageNo] = useState(1);

useEffect(() => {ref?.current?.addEventListener('scroll', handleScroll);}, [showDropdown]);

// here ref is refering to a dropdown div , wherein I check the dropdown menu scroll, in the handleScroll function where if the stated condition is met, the function fetchNextList() gets called. I have ommitted the dropdown menu code as it is unnecessary here.

const handleScroll = () => {

let bottom = ref?.current?.scrollHeight - ref?.current?.scrollTop -ref?.current?.clientHeight < 50

if (bottom) {fetchNextList();}else { return; }

}

const fetchNextList = async () => {

setSearchPageNo(searchPageNo+1); // here is where the value of searchPageNo doesn't get incremented.

if (searchText === undefined)

{searchText = "";}

let info = {"pageNo":searchPageNo ,"pageSize": 10,}

await API( "xxxxxx","post", info).then((res) => {// some code}).catch((error) => {console.log(error.response); });\```

}

}

🌐
BOSC Tech Labs
bosctechlabs.com › home › blog › how to solve changes not reflecting when usestate set method applied?
Steps to Solve Changes Not Reflecting When useState Set Method Applied
August 1, 2024 - When the “useState” set method is not reflecting a change immediately, it may be due to the current closure of the state variable. Hence, it is still referring to the old value of the state.
🌐
DhiWise
dhiwise.com › post › react-usestate-set-not-working-here-how-to-fix-it
The Fix for React useState Set Not Working
September 5, 2024 - Instead, React batches state updates for performance reasons, undertaking them in a way that optimizes rendering. A common misconception with useState is expecting the state to reflect the new value immediately after the setter function is called. This expectation can lead to elusive bugs when your following logic depends on the updated state.
🌐
freeCodeCamp
forum.freecodecamp.org › javascript
React useState not updating the variable - JavaScript
April 14, 2023 - Problem There is no syntax errors. Function parseLocalStorage returns a object White using setStorage(parseLocalStorage()) at useState Storage does’nt get modified setStorage used in other functions (like { const [hasParsed , setH...
🌐
www.namespaceit.com
namespaceit.com › blog › react-usestate-set-method-not-reflecting-change-immediately
[Solved] React useState set method not reflecting change immediately | NamespaceIT
So the process to update React state is asynchronous for performance reasons. That’s why changes don’t feel immediate. Even if you add a setTimeout function, though the timeout will run after some time.
🌐
Designdebt
designdebt.club › usestate-values-not-updating-in-react
useState values not updating in React – designdebt.club
In order to increment correctly, however, it needs to know the current count at the time the interaction occurs — Which it doesn’t. It only knows the count that was applied at the time the event listener was set. Note: The app object and event app.on('incremented-externally',...) is just something I made up to simplify the code, it’s not real and won’t work. A solution I found somewhere online (I don’t remember where unfortunately), is to add a Ref into the mix. const ClickCountButton = () => { const [count, setCount] = React.useState(0); const handleClick = (e) => { setCount( count+
🌐
Codinn
codinn.dev › articles › setstate-not-updating-state-immediately-in-functional-component
setState not updating State immediately in Functional Component
May 24, 2023 - In this example, we define a component called MyComponent that utilizes the useState Hook. We initialize the count state variable to 0 and provide a function-based increment handler. Notice how we call setCount multiple times inside the increment function, each time using the previous count to calculate the updated count. By doing so, we ensure immediate state updates without falling into the batching trap!
🌐
GeeksforGeeks
geeksforgeeks.org › does-react-usestate-hook-update-immediately
Does React useState Hook update immediately ? | GeeksforGeeks
November 28, 2023 - The useState hook is a function that allows you to add state to a functional component. It is an alternative to the useReducer hook that is preferred when we require the basic update. useState Hooks are used to add the state variables in the components.
🌐
GitHub
github.com › facebook › react › issues › 14794
useState doesn't update component · Issue #14794 · facebook/react
February 8, 2019 - It does change the variable page but the component itself never re renders or shows the current value of the variable. react and react-dom are version 16.8.1 babel-core is 6.26.0 · const AssessmentWizard = (props) => { let [page, setPage] = useState(1) return ( <div> {page} <Button onClick={() => setPage(page--)}>Previous Page</Button> <Button onClick={() => setPage(page++)}>Next Page</Button> </div> ) }
Author   ThinkSalat
🌐
Medium
medium.com › @hammadrao891 › value-doesnt-change-on-usestate-cd9bc384fb3b
Value doesn’t change on useState?! | by Hammad Rao | Medium
April 26, 2023 - If React updated the state immediately, ... in the same function. In summary, when you use useState to update the state in a React functional component, the update doesn't happen immediately....
🌐
Medium
medium.com › ableneo › react-setstate-does-not-immediately-update-the-state-84dbd26f67d5
React setState does not immediately update the state | by Marcel Mokos | ableneo tech & transformation | Medium
May 19, 2022 - Returns a stateful value, and a function to update it. The function to update the state can be called with a new value or with an updater function argument. const [value, setValue] = useState("");setValue("React is awesome!");