I am trying to figure out if useMemo
has a cache table that maps dependencies with results.
Here are two code samples:
#1:
const [a, setA] = useState(0);
const aSquare = useMemo(() => {
console.log("recalculating aSquare value");
return a ** 2;
}, [a]);
#2:
// Custom hook that returns value calculated by processor function whenever deps (dependencies array) changes
// Of course, hook is declared outside of react component
export const useDependentValue = (processor, deps) => {
const [value, setValue] = useState(processor());
useEffect(() => {
const updateValue = () => {
setValue(processor());
};
updateValue();
}, deps);
return value;
};
import { useDependentValue } from './hooks';
const [a, setA] = useState(0);
const aSquare = useDependentValue(() => {
console.log("recalculating aSquare value");
return a ** 2;
}, [a]);
In both cases I have a two variables:
a
aSquared
, which is "derived"/"dependent" on changes froma
React documentation of useMemo
says:
useMemo
is a React Hook that lets you cache the result of a calculation between re-renders.
But the Wikipedia page for memoization says:
Memoization is an optimization technique used primarily to speed up computer programs by storing the results of expensive function calls to pure functions and returning the cached result when the same inputs occur again.
If we run sample #1 and play with the value of a
by calling setA
with different numbers we’ll see that it works just like React documentation says – useMemo
"saves" us from unwanted re-calculations (when component re-render is caused by something else like prop changes etc). But re-calculation still happens even if a value repeats itself (like setA(10)
, then setA(2)
, then again setA(10)
).
Suppose useMemo
were doing "classic" memoization, then on the third time instead of recalculating the value, it should be taken from the cache.
My questions are:
- Does useMemo actually memoize (with caching) or it’s only preventing unwanted recalculation like when component re-renders but dependencies did not change?
- Are there any serious differences between code samples #1 and #2?
- Are there any cases when
useDependentValue
should be used instead ofuseMemo
for better performance? - If dependency array contains some large objects is it better to use
useDependentValue
instead ofuseMemo
in order to create "dependent" values? Or performance will be the same? (I guess ifuseMemo
actually has some cache table then for large objectsuseDependentValue
should be better).
2
Answers
reading through their documentation and putting these lines together really looks to indicate that it is only for the most recent value based on the direct dependencies changing:
to your point it is like memoization definition from wikipedia but not exact as it isn’t as smart as an actual cache like map
also would be a fantastic feature for them to add!!
Under the hood, useMemo in React works by storing the dependencies (deps) in a reference each time it is executed. It constantly monitors these dependencies for any changes. If there are changes or if the dependencies are undefined, useMemo will re-run the provided callback function and store its results for future use. However, if the dependencies remain unchanged, useMemo returns the previously memoized value, optimizing performance.
here is my implementation of useMemo which does the same thing.