Skip to content

Bug: strict mode, initial state changes, and useMemo (with dependency) doesn't seem to be recomputed #21178

Closed
@aliak00

Description

@aliak00

React version: 17.0.2

I ran in to this interesting dynamic that I cannot explain today.

  1. The code sets some initial state, which is a random number, and logs this initial value.
  2. It converts the number to a string using useMemo, which logs the number it is converting, and is dependant on that number (not the string). And
  3. when the component is mounted, I force a re-render by changing a boolean state once.

The result is that the initial value of the number is changed (and the log is output) so you see the number being set twice to two different values - this only happens in StrictMode. It is surprising. Is it expected?

You also see the useMemo being computed ONCE - only the first time. So seemingly it does not recompute a new string value.

BUT, the output in the HTML is the correct and shows the stringified value of the second number.

So what is happening here? Is the console log swallowed? Is useMemo behaving correctly, and more importantly, is the initialValue of useState supposed to change like that?

Steps To Reproduce

export default function App() {
  const [rand] = useState(Math.random());
  const [, setState] = useState(false);

  console.log(`Number: ${rand}`);

  useEffect(() => {
    setState(true);
  }, []);

  const text = useMemo(() => {
    console.log(`Computing text from ${rand}`);
    return rand.toString();
  }, [rand]);

  return (
    <div className="App">
      <h1>Rand: {rand}</h1>
      <h1>Text: {text}</h1>
    </div>
  );
}

And wrap your app in StrictMode

Link to code example:

https://codesandbox.io/s/strict-mode-random-bug-ml3gv

The current behavior

initial state computed twice.
usememo seemingly not run twice

The expected behavior

Initial state computed once?
Or usememo runs twice?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions