useMemo
useMemo
useMemo is a React Hook that lets you cache the result of a calculation between renders. This process of caching a value is known as memoization.
Syntax
const cachedValue = useMemo(calculateValue, dependencies)
calculateValue: A pure function calculating the value you want to cache. It should take no arguments and return any type.dependencies: An array of reactive values (props, state) referenced inside thecalculateValuefunction.
How it works
On the initial render, useMemo calls calculateValue and returns its result.
During subsequent renders, React compares the current dependencies with the previous ones. If none of the dependencies have changed, useMemo returns the already calculated value. If a dependency has changed, it re-runs calculateValue, returns the new result, and stores it for the next time.
Primary Use Case 1: Skipping expensive recalculations
If you have a function that takes a significant amount of time to run (e.g., filtering a list of 10,000 items, or doing heavy math), you don’t want it to run on every single render if its inputs haven’t changed.
function TodoList({ todos, tab }) {
// ✅ The expensive filtering only re-runs if 'todos' or 'tab' changes.
// If the user types in a completely unrelated input field triggering a re-render,
// this filtering step is skipped entirely.
const visibleTodos = useMemo(
() => filterTodos(todos, tab),
[todos, tab]
);
return (
// ...
);
}
Primary Use Case 2: Preserving object/array references
In JavaScript, two newly created objects are never equal ({} === {} is false).
If you pass an object or array down as a prop to an optimized child component (e.g., a component wrapped in React.memo), the child will re-render every time the parent renders, because the object reference changes on every render.
You can use useMemo to ensure the object reference stays exactly the same unless its contents actually change.
function ParentComponent({ userId, data }) {
// If we just passed { id: userId } inline, the reference would change every render.
// By memoizing it, the reference stays stable.
const userConfig = useMemo(() => {
return { id: userId, theme: 'dark' };
}, [userId]);
return <MemoizedChild config={userConfig} />;
}
Overusing useMemo
Don’t wrap everything in useMemo. Memoization itself has a performance cost (React has to store the previous values and compare dependencies on every render). Only use it for genuinely expensive operations or to preserve referential equality for child components that strictly require it.
Interview Questions
Q: What is the difference between useMemo and useCallback?
A: useCallback memoizes a function definition. useMemo memoizes the result of executing a function.
Q: When should you use useMemo?
A: You should use it to cache the result of a highly expensive, CPU-intensive mathematical calculation or massive array sorting/filtering operation, ensuring the math isn’t re-run on every single render unless the data actually changes.