React useMemo Hook
The useMemo
hook is used in React to optimize performance by memoizing expensive calculations. It ensures that a computed value is only recalculated when its dependencies change, rather than on every render. This can significantly improve performance in components with heavy computations or frequent re-renders.
1. Example: Expensive Calculation using useMemo Hook
In this example, we use useMemo
to memoize the result of an expensive calculation. Without useMemo
, the calculation would run on every render, even if the inputs remain unchanged.
Consider the following example, where the rendering can be triggered by the change in input for factorial calculation or, Toggle Other Value button. useMemo
helps to remember the value of factorial, even when the re-render is triggered by Toggle Other Value button.
App.js
import React, { useState, useMemo } from 'react';
function ExpensiveCalculation() {
const [number, setNumber] = useState(0);
const [otherValue, setOtherValue] = useState(false);
const factorial = useMemo(() => {
console.log('Calculating factorial...');
const calculateFactorial = (n) => {
if (n <= 1) return 1;
return n * calculateFactorial(n - 1);
};
return calculateFactorial(number);
}, [number]); // Recomputes only when 'number' changes
return (
<div>
<h2>Factorial of {number}: {factorial}</h2>
<input
type="number"
value={number}
onChange={(e) => setNumber(Number(e.target.value))}
/>
<br />
<br />
<button onClick={() => setOtherValue(!otherValue)}>Toggle Other Value</button>
<p>Other Value: {otherValue ? 'True' : 'False'}</p>
</div>
);
}
export default ExpensiveCalculation;
Explanation:
useMemo
: Memoizes the result of the factorial calculation and re-computes only whennumber
changes.- The factorial function is expensive, but with
useMemo
, it avoids unnecessary recalculations during renders triggered by other state changes (likeotherValue
).
Output:
2. Example: Filtering a Large List using useMemo Hook
Here, we use useMemo
to optimise the filtering of a large list of items. The filtering logic is only executed when the search query changes, reducing unnecessary computations on each render.
App.js
import React, { useState, useMemo } from 'react';
function FilteredList() {
const [search, setSearch] = useState('');
const items = ['Apple', 'Banana', 'Cherry', 'Date', 'Elderberry', 'Fig', 'Grape'];
const filteredItems = useMemo(() => {
console.log('Filtering items...');
return items.filter(item => item.toLowerCase().includes(search.toLowerCase()));
}, [search]); // Recomputes only when 'search' changes
return (
<div>
<input
type="text"
value={search}
onChange={(e) => setSearch(e.target.value)}
placeholder="Search items"
/>
<ul>
{filteredItems.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
</div>
);
}
export default FilteredList;
Explanation:
useMemo
: Ensures the filtering logic is executed only when thesearch
value changes.- This optimization avoids recalculating the filtered list on every render, which is particularly useful for large datasets.
Output:
3. Example: Derived State using useMemo Hook
In this example, we calculate the sum of a list of numbers using useMemo
. The sum is recomputed only when the list of numbers changes, not when other unrelated state changes occur.
App.js
import React, { useState, useMemo } from 'react';
function SumCalculator() {
const [numbers, setNumbers] = useState([1, 2, 3, 4, 5]);
const [otherState, setOtherState] = useState(false);
const sum = useMemo(() => {
console.log('Calculating sum...');
return numbers.reduce((total, num) => total + num, 0);
}, [numbers]); // Recomputes only when 'numbers' changes
const addNumber = () => {
setNumbers([...numbers, numbers.length + 1]);
};
return (
<div>
<h2>Sum: {sum}</h2>
<button onClick={addNumber}>Add Number</button>
<br />
<button onClick={() => setOtherState(!otherState)}>Toggle Other State</button>
<p>Other State: {otherState ? 'True' : 'False'}</p>
</div>
);
}
export default SumCalculator;
Explanation:
useMemo
: Calculates the sum of the array only when thenumbers
array changes.- Adding a new number updates the sum, while toggling
otherState
does not trigger the sum calculation.
Output:
Conclusion
The useMemo
hook is a powerful tool for optimising performance in React applications. By memoizing expensive calculations, it ensures that computations are only performed when necessary. Use useMemo
whenever you encounter expensive operations or components with frequent renders to keep your application efficient.