nanxiaobei
nanxiaobei

Reputation: 51

Why setState(contains another setState inside) after promise be called twice?

Why setState(contains another setState inside) after promise be called twice?

Demo code:

https://codesandbox.io/s/setstate-issue-v1fpv

const App = () => {
  const [a, setA] = useState(0);
  const [b, setB] = useState(0);

  const onClick = async () => {
    await new Promise((r) => setTimeout(r));
    // when after promise, setB called twice
    // remove promise, setB called once

    setB((prevB) => {
      console.log("setB");

      setA((prevA) => prevA + 1);
      return prevB + 1;
    });
  };

  return (
    <>
      {a} | {b} | <button onClick={onClick}>+1</button>
    </>
  );
};

Upvotes: 1

Views: 95

Answers (1)

nanxiaobei
nanxiaobei

Reputation: 51

For those who also confused, here is the answer from React docs:

Strict mode can’t automatically detect side effects for you, but it can help you spot them by making them a little more deterministic. This is done by intentionally double-invoking the following functions:

  • Class component constructor, render, and shouldComponentUpdate methods
  • Class component static getDerivedStateFromProps method
  • Function component bodies
  • State updater functions (the first argument to setState)
  • Functions passed to useState, useMemo, or useReducer Note:

This only applies to development mode. Lifecycles will not be double-invoked in production mode.

https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects

https://github.com/facebook/react/issues/21114#issuecomment-808697394

Upvotes: 1

Related Questions