First we need to understand what memoization is. Memoization is an optimization technique, in which we accelerate our programs by caching the results of heavy function calls for the same inputs.
In simple terms, for example we have an input say '2' and we pass it through our function which takes a lot of time to execute. Now, if we need to calculate the result for input '2' again then we need to perform the function again and it will again take that much time.
But not if we used memoization in the first go, if we memoize the output for '2' of that function then we just need to get that value from our memoized values and don't need to execute that function again for '2', which in term will save us the time it takes for execution, and will make our program much more optimized.
In this post we will understand how to use useMemo
React hook
useMemo()
useMemo
is a React Hook that lets you cache the result of a calculation between re-renders. It accepts 2 arguments- a function that computes a result, and the depedencies
array:
const memoizedValue = useMemo(calculateValue, dependencies)
During initial rendering, useMemo(calculateValue, dependencies)
invokes calculateValue, memoizes the calculation result, and returns it to the component.
If the dependencies don't change during the next renderings, then useMemo()
doesn't invoke calculateValue
, but returns the memoized value.
But if the dependencies change during re-rendering, then useMemo()
invokes calculateValue
, memoizes the new value, and returns it.
const memoizedResult = useMemo(() => {
return heavyFunction(A, B);
}, [A, B]);
In this case we have two dependencies A and B, so for the first render it will let the heavyFunction
run to get the output, but in the re-renders if the dependencies don't change then it'll not execute the function and will return the memoized value.
Example
Let's take example of a classic recursion problem of calculating a factorial.
In factorial we often have the same input and without memoization the function always keeps on going to calculate the result, but if we memoize the output for a value and return that then we will save a lot of recursion cycles and will just return the memoized value at that point only.
function fact(n) {
if(n <= 0){
return 1;
}
return n * fact(n - 1);
}
So this is a simple implementation of factorial of a number n using recursion.
Now, if we have a whole component for this:
import { useState, useMemo } from 'react';
export function CalculateFactorial() {
const [number, setNumber] = useState(5);
const factorial = useMemo(() => fact(number), [number]);
const onChange = event => {
setNumber(Number(event.target.value));
};
return (
<div>
Factorial of
<input type="number" value={number} onChange={onChange} />
is {factorial}
</div>
);
}
function fact(n) {
console.log('factorial called!');
if(n <= 0){
return 1;
}
return n * fact(n - 1);
}
Every time you change the value of the number, factorial called!
is logged to console. That's expected.
However, if we Re-render without changing the number, factorial called!
isn't logged to console because useMemo(() => fact(number), [number])
returns the memoized factorial calculation. And hence saving us from calling the function again and recalculating.
useMemo()
is a Hook, so you can only call it at the top level of your component or your own Hooks. You canβt call it inside loops or conditions.
I hope now you understand how useMemo
works in React.
Thanks for reading.
Top comments (0)