In my component, I'm using useMemo
to run and cache a somewhat expensive query to the browser runtime. So far, it has cut back dramatically on the time required for subsequent renders.
However, the actual first render is still a problem. I'm rendering thousands of instances of my component at once, and it seems that the expensive query gets repeated unnecessarily. The same query result could be used for a lot of those instances, as I'm using only two or three unique inputs for the query at once. The query could be considered pure, as it consistently returns the same result for the same inputs.
I'm left wishing that the memoized return value was available to other instances of the same component, but the profiling data suggests that it is not.
Is there a clean and sustainable way to ensure that a memoized result is shared across all calls to the same function, regardless of the originating component instance?
useMemo() is a React Hook that we can use to wrap functions within a component. We can use this to ensure that the values within that function are re-computed only when one of its dependencies change.
useMemo() function can memoize the value returned by your function and keep it in memory across renders. In most situations, it returns a result that you can't run outside of your React component.
I'll explain those three one by one though at first I will show the basic idea. Simply, React. memo is related to 'component', useMemo is related to 'value', useCallback is related to function. To be precise, useMemo return a value, useCallback return a function.
The state that is maintained by React hooks is specific to component instance where they are called.
In order for useMemo
or useCallback
to have a common state for multiple component instances, they should occur in nearest common parent and be provided with context API to deeply nested children if needed.
In case it should behave in a different way, general-purpose memoization utility should be used, like Lodash memoize
:
const expensiveFn = () => ...;
const memoizedExpensiveFn = _.memoize(expensiveFn);
It also allows to have control over cache storage:
memoizedExpensiveFn.Cache = ES6MapWithExpiration;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With