useMemo / useCallback cache busting opt out
See original GitHub issueAccording to the React
docs, useMemo
and useCallback
are subject to cache purging:
You may rely on useMemo as a performance optimization, not as a semantic guarantee. In the future, React may choose to “forget” some previously memoized values and recalculate them on next render, e.g. to free memory for offscreen components. Write your code so that it still works without useMemo — and then add it to optimize performance. source
I am working on moving react-beautiful-dnd
over to using hooks https://github.com/atlassian/react-beautiful-dnd/issues/871. I have the whole thing working and tested 👍
It leans quite heavily on useMemo
and useCallback
right now. If the memoization cache for is cleared for a dragging item, the result will be a cancelled drag. This is not good.
My understanding is that useMemo
and useCallback
are currently not subject to cache purging based on this language:
In the future, React may choose to “forget”
Request 1: Is it possible to opt-out of this cache purging? Perhaps a third options
argument to useMemo
and useCallback
:
const value = useMemo(() => ({ hello: 'world' }), [], { usePersistantCache: true });
(Naming up for grabs, but this is just the big idea)
A work around is to use a custom memoization toolset such as a useMemoOne
which reimplements useMemo
and useCallback
just using ref
s see example
I am keen to avoid the work around if possible.
Request 2: While request 1 is favourable, it would be good to know the exact conditions in which the memoization caches are purged
Issue Analytics
- State:
- Created 4 years ago
- Reactions:37
- Comments:36 (11 by maintainers)
@alexreardon
useCallback
docs do not say that it is subject to cache purging. Docs are not clear enough here though.Docs only say that:
If
useCallback
is equivalent touseMemo
, why we haveuseCallback
at all? I assume if there is a separateuseCallback
hook shipped with React there is a reason for that and that reason is not documented well.I think this is an uncommon enough case that using
useRef
to implement your own stable references is the right approach.I don’t think it’s valuable to document the internal caching strategy beyond “React might clear the cache when it needs to” since it’s likely to be dynamic and difficult to predict. No single component could predict cache hits or misses at runtime with any certainty.
Just a heads up that this is likely to be problematic in concurrent mode, since the function might be called many times with different props.