TASIOMIND.DEV — OPERATIONAL▸▸▸FULL STACK DEVELOPER @ GWQ SERVICEPLUS AG▸▸▸FOUNDER — K8SGPT.AI▸▸▸OPEN SOURCE: ACTIVE▸▸▸DISTRIBUTED SYSTEMS / KUBERNETES / AI▸▸▸RUST + GO + PYTHON▸▸▸FIELD TESTED / STATUS — NOMINAL▸▸▸LOCATION: EUROPE/BERLIN▸▸▸TASIOMIND.DEV — OPERATIONAL▸▸▸FULL STACK DEVELOPER @ GWQ SERVICEPLUS AG▸▸▸FOUNDER — K8SGPT.AI▸▸▸OPEN SOURCE: ACTIVE▸▸▸DISTRIBUTED SYSTEMS / KUBERNETES / AI▸▸▸RUST + GO + PYTHON▸▸▸FIELD TESTED / STATUS — NOMINAL▸▸▸LOCATION: EUROPE/BERLIN▸▸▸

Why is my state not getting updated - Hooks version

October 18, 2019

Probably because you are using it wrong.

Find class based version here

code
const [value, setValue] = useState("");
function handleChange(newValue) {
  setValue(newValue);
  console.log(value);
}

Why is your state not getting updated?

Straight out of React docs, setState may be asynchronous. What does that mean?

Let’s find out.

code
setTimeout(() => console.log("foo"), 0);
console.log("bar");

What is the output?

First the second console.log fires and then the first one inside the setTimeout function. This happens because setTimeout is asynchronous and is moved to the browser thread. So the code that runs after setTimeout gets executed however small the timeout is.

Same is the case with setState Because of it’s asynchronous state, the statement after is being called before the actual setState function.


How do we fix this?

React calls the functional component once again whenever the state is updated. Hence, to see the updated state, just look in the render.

code
function App() {
  const [value, setValue] = useState("");
  function handleChange(newValue) {
    setValue(newValue);
  }
  console.log(value);
  ...
}

But in real world react components, there would be multiple states (and props) and this would trigger the console.log every time any one of these is updated. Instead, a more effective approach would be:

code
function App() {
  const [value, setValue] = useState("");
  useEffect(() => {
    console.log(value);
  }, [value]);
  function handleChange(newValue) {
    setValue(newValue);
  }
  ...
}

Note that the useEffect has the required state as dependency and thus would run whenever it is changed.