Description
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.