Home > Net >  Not updating the State inside the function but updating in useEffect
Not updating the State inside the function but updating in useEffect

Time:09-02

I'm a beginner to React JS.

I faced this weird situation,

const [counter, setCounter] = useState(0);

  const incrementCounter = () => {
    setCounter(counter   1);
    console.log(counter, "Log inside the function");
  };

  useEffect(() => {
    console.log(counter, "Log inside the useEffect");
  }, [counter]);

  return (
    <div>
      <h1>{counter}</h1>
      <button onClick={incrementCounter}>Increment</button>
    </div>
  );

So when incrementCounter function is triggered counter value will be increased by 1 and right after that I'm logging the value in the console. But it displays the value as 0. When I use the useEffect hook to check the changes of count state it I'm getting the correct value as 1 when I log the count value inside the useEffect scope. What is the reason for not displaying in incrementCounter function and the reason for displaying the correct value inside the useEffect hook. Please I need a clear explanation, Try not to downvote thanks.

CodePudding user response:

States value will change only after the component has rendered.

In this case the log inside the function will keep the state value even after the SetCounter, once it completes the component will render again.

The useEffect is triggered when the state has changed on such render so it shows the new value.

CodePudding user response:

A new incrementCounter function object is being redefined with every render. Each time it is defined, its own internal counter is based on the counter state is at that point. The counter within that particular incrementCounter function object is stale and doesn't get updated anymore.

CodePudding user response:

according to React docs

Think of setState() as a request rather than an immediate command to update the component. For better perceived performance, React may delay it, and then update several components in a single pass. In the rare case that you need to force the DOM update to be applied synchronously, you may wrap it in flushSync, but this may hurt performance.

setState() does not always immediately update the component. It may batch or defer the update until later. This makes reading this.state right after calling setState() a potential pitfall. Instead, use componentDidUpdate or a setState callback (setState(updater, callback)), either of which are guaranteed to fire after the update has been applied. If you need to set the state based on the previous state, read about the updater argument below.

  • Related