5

When running the run function, I expect that value variable has value 'new', but since even 500 ms, it still remains 'old'. Why that happens and how coud this issue be solved?

import React, { Component, useState } from "react";
import { render } from "react-dom";

function App() {
  const [value, setValue] = useState('old');

  const run = async() => {
    setValue('new')
    const data = await wait(500)
    console.log(value)
  }

  return (
    <button onClick={run}>
      Run
    </button>
  );
}

render(<App />, document.getElementById("root"));

function wait(ms) {
  return new Promise(resolve => setTimeout(resolve, ms))
}
3
  • Even if you are using a class component also if you access state suddenly you can't see the changes, if you need to see the data then you need to call the callback of this.setState, addition to this in promise setState behaves sync and in events it behaves async in React 17 they are trying to solve this issue by using concurrent mode. Commented Dec 20, 2019 at 5:14
  • 3
    I don't think this should be flagged as a duplicate. useState set method not reflecting change immediately, which is regarding a delayed state change. This question concerns a state that never changes. All the answers are misunderstanding the question also. When you use async notation, state cannot be viewed inside async function. It can however be updated. Commented Nov 24, 2020 at 15:51
  • did you found the answer? Commented Mar 18, 2021 at 13:28

3 Answers 3

4

setState runs asynchronously so it is not immediately reflected in the function code block. You can try using useEffect to watch changes of your state.

useEffect(() => console.log('value', value), [value])

Sign up to request clarification or add additional context in comments.

Comments

0

In your case const [value, setValue] = useState('old'); setValue is nothing but same like setState in class Components. So since setState and setValue is asynchronous functions, you can never predict when the values will get updated.

So either you can use componentDidUpdate in class components or useEffect like useEffect(() => callFn();, [value]) . so here callFn() is afunction which will be called after value has been updated.

hope it helps. feel free for doubts

Comments

0

Ok, here is what I think is happenning: You click the button, which calls your run function - then the run function calls setState.

  • I think setState is supposed to cause a rerender of the component with the new value which would be shown immediately if you were displaying it somewhere. So if you want to see immediate changes, add a display.
  • When you console log in the run function immediately after setState, the component has not been rerendered which means you are still looking at the old value.
  • When the component rerenders, you are not seeing the console logged value because the run function has not been called again. Clicking the button twice should console log the new value because by then the component has rerendered with that new value.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.