0

I have a general question about useEffect() vs setTimeout().

import { useState, useEffect } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  useEffect(() => console.log(count)); // effect

  const handleClick = () => {
    setCount(count + 1);
    setTimeout(() => console.log(count), 5000); // log to console after 5 seconds
  }

  return (
    <>
      <p>You clicked {count} times</p>
      <button onClick={handleClick}>Click Me</button>
    </>
  );
}

export default Counter;

In the above code,

setCount(count + 1);
setTimeout(() => console.log(count), 5000);

using setTimeout(), I am trying to log count after 5 seconds, by which time setCount(), although asynchronous, would have definitely finished.

Then why does that still print the previous value of count, while useEffect() code prints the updated value? Can someone tell me what I am missing.

user637563
  • 346
  • 3
  • 15

1 Answers1

0

A lot of things to say about this code:

import { useState, useEffect } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  useEffect(() => console.log(count), [count]); // Add the dependencies array, the callback of use effect will be call only if a dependency is updated

  const handleClick = () => {
    setCount((count) => count + 1); // Use a callback which takes as argument the previous state, because if you click multiple times on the button, as setCount is asynchronous, it won't add 1 for each click
    setTimeout(() => console.log(count), 5000); // log to console after 5 seconds
  }

  return (
    <>
      <p>You clicked {count} times</p>
      <button onClick={handleClick}>Click Me</button>
    </>
  );
}

export default Counter;

I think that it is because the callback of setTimeout is evaluated before the njew count variable is computed, so it logs the previous value, where useEffect's callback is called when a dependency is updated, so when you increment count.

ocheriaf
  • 580
  • 3
  • 11