0

I am looking at example at https://github.com/mrdulin/react-act-examples/blob/master/sync.md

function App() {
  let [counter, setCounter] = useState(0);
  return <button onClick={() => setCounter(counter + 1)}>{counter}</button>;
}

test one, it works

it("should increment a counter", () => {
  const el = document.createElement("div");
  document.body.appendChild(el);
  // we attach the element to document.body to ensure events work
  ReactDOM.render(<App />, el);
  const button = el.childNodes[0];

  for (let i = 0; i < 3; i++) {
    button.dispatchEvent(new MouseEvent("click", { bubbles: true }));
  }

  expect(button.innerHTML).toBe("3");
});

test two, doesn't work

it("should increment a counter", () => {
  const el = document.createElement("div");
  document.body.appendChild(el);
  // we attach the element to document.body to ensure events work
  ReactDOM.render(<App />, el);
  const button = el.childNodes[0];

  act(() => {
    for (let i = 0; i < 3; i++) {
      button.dispatchEvent(new MouseEvent("click", { bubbles: true }));
    }
  });

  expect(button.innerHTML).toBe(3); // this fails, it's actually "1"!
});

I still don't understand how first testworks, as the author mentions that:

if the handlers are ever called close to each other, it's possible that the handler will use stale data and miss some increments

then why the first test doesn't subject to this rule? why it doesn't use stale data like test two?

lch
  • 125
  • 7
  • 1
    Most likely “by accident.” Doing the handlers that way can always use stale data, it just happens to run the handlers differently. Not sure if there’s any importance in knowing why it seems to work (note: only seems to, it doesn’t always work), the point is that this kind of code should not be written. A bit like “undefined behavior” – Sami Kuhmonen Aug 02 '23 at 03:16
  • See also [Why React useState with functional update form is needed?](https://stackoverflow.com/q/57828368/283366) – Phil Aug 02 '23 at 03:25
  • @SamiKuhmonen based on the answer https://stackoverflow.com/a/73115899/21769004 the code is valid, even react hooks official docs uses the same code https://legacy.reactjs.org/docs/hooks-state.html – lch Aug 03 '23 at 00:08

0 Answers0