Skip to content

useMemo factory being called more frequently / unnecessarily #3616

Closed
@wnayes

Description

@wnayes

There seems to have been a change with useMemo around the 10.8.1 release, I believe starting with PR #3567.

When a state updater is called during render, and a useMemo hook is present, the memo "factory" function will get called more than once. The prior behavior was that we would reuse the memoed value from the first render.

I believe this is because the code now stores the computed value in _pendingValue and doesn't copy it over to _value until a later point. Renders triggered by a state updater must be happening quicker than this copy over, causing the work to be lost.

To Reproduce

https://codesandbox.io/s/goofy-cherry-emgdox?file=/index.js

A demo component illustrates the behavior.

let idState = 0;
function createId() {
  return "_id" + ++idState;
}

const TestComp = () => {
  const id = useMemo(() => createId(), []);
  const [stateId, setStateId] = useState("");

  if (!stateId) {
    setStateId(id);
  }
  return <div>Last id from memo: {id}</div>;
};

render(<TestComp />, window.root);

The browser displays "Last id from memo: _id2" indicating that createId (the function being memoized) was called twice.

Expected behavior
I would expect the memoized computations not to be lost between renders, even if they are happening in quick succession.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions