What is useMemo hook?
The `useMemo` hook in React is a powerful tool for performance optimization. It allows you to memoize the result of a computation, preventing unnecessary re-calculations during component re-renders when its dependencies haven't changed.
What is useMemo?
useMemo is a React Hook that takes two arguments: a 'factory' function that computes a value, and a dependency array. It returns a memoized value. React will only re-run your factory function if one of the dependencies in the array has changed since the last render.
Its primary purpose is to prevent expensive calculations from being re-executed on every render, thereby improving the performance of your application, especially in components that re-render frequently or deal with complex data transformations.
How it works
When your component first renders, useMemo calls your factory function and stores its result. On subsequent renders, if the values in the dependency array are the same (compared using shallow equality) as they were in the previous render, useMemo will return the previously stored value without re-executing the factory function. If any dependency has changed, it will re-run the factory function and store the new result.
import React, { useMemo, useState } from 'react';
function calculateExpensiveValue(num) {
console.log('Calculating expensive value...');
let sum = 0;
for (let i = 0; i < num * 10000000; i++) {
sum += i;
}
return sum;
}
function MyComponent() {
const [count, setCount] = useState(0);
const [number, setNumber] = useState(100);
// This calculation will only re-run when 'number' changes
const memoizedExpensiveValue = useMemo(() => calculateExpensiveValue(number), [number]);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment Count</button>
<p>Number: {number}</p>
<button onClick={() => setNumber(number + 100)}>Change Number</button>
<p>Expensive Value: {memoizedExpensiveValue}</p>
</div>
);
}
When to use useMemo?
- Expensive Calculations: When you have a function that performs a computationally intensive task, and its result doesn't need to be re-calculated unless specific inputs change.
- Referential Equality: To prevent unnecessary re-renders of child components that are wrapped in
React.memo(). If you pass an object or array literal as a prop, it will be a new reference on every render.useMemocan ensure a consistent reference as long as its dependencies don't change. - Dependencies for other Hooks: When a value is used as a dependency for another Hook, like
useEffectoruseCallback, memoizing that value can prevent those Hooks from re-running unnecessarily.
When NOT to use useMemo?
It's important not to overuse useMemo. Memoization itself has a cost (memory to store the previous value, and CPU time to compare dependencies). For simple calculations, the overhead of useMemo might outweigh the performance benefits.
Always profile your application to identify actual performance bottlenecks before reaching for useMemo. It's an optimization tool, not a default pattern.
Key Considerations
useMemoruns during rendering, so your factory function should be pure (it should not cause side effects).- React might 'forget' some memoized values and re-calculate them during the next render (e.g., to free up memory). Do not rely on
useMemofor state management or to ensure the value never changes. - An empty dependency array
[]means the memoized value will be calculated once on the initial render and never again, useful for static values. - Omitting the dependency array will cause the function to run on every render, effectively defeating the purpose of
useMemo.