How to Implement useMemo Hook in React
This article provides a straightforward guide on how to implement the
useMemo Hook in React to optimize application performance.
You will learn what useMemo is, when to use it to prevent
unnecessary calculations during re-renders, and how to write the code
with a practical step-by-step example.
Understanding useMemo
The useMemo Hook is a built-in React Hook that caches
(memoizes) the result of a calculation between renders. In React,
whenever a component’s state or props change, the entire component
re-renders, re-running all functions inside it. If you have an expensive
calculation, running it on every render can slow down your application.
useMemo solves this by only recalculating the value when
one of its dependencies changes.
Basic Syntax
The useMemo Hook accepts two arguments: a function that
returns the value you want to cache, and an array of dependencies.
const memoizedValue = useMemo(() => {
return computeExpensiveValue(a, b);
}, [a, b]);- The calculate function: A function with no arguments that returns the value you want to compute.
- The dependency array: A list of all reactive values (props, state, and variables) referenced inside the calculation function.
Step-by-Step Implementation
Here is a practical example of how to implement useMemo
in a React component. In this example, we have a component with a heavy
filtering operation and an unrelated counter button.
1. Import useMemo
First, import the Hook from the React library.
import React, { useState, useMemo } from 'react';2. Define the Component and State
Set up your component with the necessary state. We will have a list of items, a search query, and an unrelated counter state.
function SearchComponent() {
const [query, setQuery] = useState('');
const [count, setCount] = useState(0);
const items = ['Apple', 'Banana', 'Orange', 'Mango', 'Pineapple', 'Grapes'];3. Implement useMemo for the Expensive Calculation
Without useMemo, the filtering logic would run every
time you click the counter button. By wrapping the filtering logic in
useMemo, it only runs when the query or
items change.
const filteredItems = useMemo(() => {
console.log('Filtering items...'); // This will only log when "query" changes
return items.filter(item => item.toLowerCase().includes(query.toLowerCase()));
}, [query]); // Only recalculate if "query" changes4. Render the Output
Complete the component by returning the JSX.
return (
<div>
<input
type="text"
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Search fruits..."
/>
<ul>
{filteredItems.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
{/* Clicking this button triggers a re-render, but does not re-run the filtering logic */}
<button onClick={() => setCount(count + 1)}>
Renders: {count}
</button>
</div>
);
}
export default SearchComponent;When to Use useMemo
You should not wrap every calculation in useMemo, as the
Hook itself has a small performance overhead. Use it in the following
scenarios:
- Expensive Calculations: When you are performing computationally heavy tasks like processing large arrays, complex data transformations, or mathematical computations.
- Preventing Unnecessary Child Re-renders: When
passing a computed object or array as a prop to a memoized child
component (wrapped in
React.memo).useMemoensures the reference to the prop remains the same unless dependencies change, preventing the child from re-rendering.