javascript – React JS: useEffect called different number of times depending upon updater function

Code Snippet #1

import React, { useEffect, useState } from "react";
import ReactDOM from "react-dom";

import "./styles.css";

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

  useEffect(() => {
    console.log("updating count...", count)
  }, [count])

  function handleClickAsync() {
    setTimeout(function delay() {
      setCount(prevCount => prevCount + 1);
    }, 3000);
  }

  return (
    <div>
      {count}
      <button onClick={handleClickAsync}>Increase async</button>
    </div>
  );
}

Code Snippet #2

import React, { useEffect, useState } from "react";
import ReactDOM from "react-dom";

import "./styles.css";

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

  useEffect(() => {
    console.log("updating count...", count)
  }, [count])

  function handleClickAsync() {
    setTimeout(function delay() {
      setCount(count + 1); //UPDATED THIS PART OF CODE!!!
    }, 3000);
  }

  return (
    <div>
      {count}
      <button onClick={handleClickAsync}>Increase async</button>
    </div>
  );
}

Codesandbox link

Can someone explain why in code snippet #1, if i click 3 times quickly, console log inside useEffect runs 3 times for each click.

But in code snippet #2, if I change the setCount inside handleClickAsync to be a simple state update (i.e. without callback function) like in below code, the useEffect now only runs once even if I click 3 times.

As I understand, React should batch state update in both cases. So why does it seem like state was not batched in case 1?

Read more here: Source link