Introduction
The useMemo Hook is used to cache the result of a calculation between renders. React can reuse the previously calculated value when its dependencies have not changed. This can be useful when a calculation is expensive and a component renders frequently. In this chapter, we will solve practical useMemo questions covering memoized calculations, dependencies, filtering, and the difference between useMemo and normal calculations. React js useMemo Hook practice questions with solutions help to understand the concepts.
1. What is the useMemo Hook in React?
useMemo is a React Hook that lets you cache the result of a calculation between renders.
Basic syntax:
import { useMemo } from "react";
const result = useMemo(() => {
return calculateSomething();
}, [dependency]);
React can reuse the cached result when the dependencies have not changed.
For example:
const total = useMemo(() => {
return price * quantity;
}, [price, quantity]);
Here, React can reuse the previous total when price and quantity remain unchanged.
2. Why is useMemo used in React?
useMemo is mainly useful for avoiding unnecessary recalculation of expensive values.
For example:
const filteredProducts = useMemo(() => {
return products.filter((product) =>
product.name.toLowerCase().includes(search.toLowerCase())
);
}, [products, search]);
The filtering calculation is re-evaluated when products or search changes.
However, useMemo should not be added everywhere. For simple and inexpensive calculations, normal JavaScript calculation is often clearer and sufficient.
3. How do you use useMemo in a React component?
Import useMemo and provide a calculation function with its dependencies.
import { useMemo, useState } from "react";
function App() {
const [number, setNumber] = useState(5);
const square = useMemo(() => {
return number * number;
}, [number]);
return (
<div>
<h2>Number: {number}</h2>
<h2>Square: {square}</h2>
<button onClick={() => setNumber(number + 1)}>
Increase
</button>
</div>
);
}
export default App;
The value stored in square is recalculated when number changes.
4. What is Memoization in React?
Memoization means caching the result of a calculation so that React can reuse it instead of calculating it again when the relevant dependencies have not changed.
For example:
const result = useMemo(() => {
return expensiveCalculation(data);
}, [data]);
If data remains the same, React can reuse the previously calculated result.
Memoization can be helpful when the calculation is expensive and repeated renders are causing unnecessary work.
5. How do you use useMemo for an expensive calculation?
Suppose a calculation takes a lot of processing time.
import { useMemo, useState } from "react";
function Calculator() {
const [number, setNumber] = useState(10);
const [theme, setTheme] = useState("light");
const result = useMemo(() => {
console.log("Calculating...");
let total = 0;
for (let i = 0; i < 1000000; i++) {
total += number;
}
return total;
}, [number]);
return (
<div>
<h2>Result: {result}</h2>
<p>Theme: {theme}</p>
<button onClick={() => setNumber(number + 1)}>
Change Number
</button>
<button
onClick={() =>
setTheme(theme === "light" ? "dark" : "light")
}
>
Change Theme
</button>
</div>
);
}
export default Calculator;
Here, the calculation depends only on number.
Changing theme does not change number, so React can reuse the memoized calculation.
6. How do you use useMemo with an Array?
useMemo can be useful when calculating a new array from existing data.
Example:
import { useMemo } from "react";
function Products({ products }) {
const availableProducts = useMemo(() => {
return products.filter((product) => product.stock > 0);
}, [products]);
return (
<div>
{availableProducts.map((product) => (
<p key={product.id}>{product.name}</p>
))}
</div>
);
}
export default Products;
The filtered array is recalculated when products changes.
This can be useful when the filtering operation is expensive or the component renders frequently.
7. How do you use useMemo for Search and Filtering?
useMemo can cache the result of a filtering operation.
import { useMemo, useState } from "react";
function ProductSearch({ products }) {
const [search, setSearch] = useState("");
const filteredProducts = useMemo(() => {
return products.filter((product) =>
product.name.toLowerCase().includes(search.toLowerCase())
);
}, [products, search]);
return (
<div>
<input
value={search}
onChange={(event) => setSearch(event.target.value)}
placeholder="Search products"
/>
{filteredProducts.map((product) => (
<p key={product.id}>{product.name}</p>
))}
</div>
);
}
export default ProductSearch;
The filtering calculation depends on:
[products, search]
Therefore, the calculation is re-evaluated when either products or search changes.
8. What happens when a useMemo dependency changes?
When a dependency changes, React recalculates the value during rendering.
Example:
const total = useMemo(() => {
return price * quantity;
}, [price, quantity]);
If price changes, React calculates the new value.
If quantity changes, React also calculates the new value.
If neither dependency changes, React can reuse the previously memoized result.
The dependency list should include the reactive values used by the calculation.
9. What is the difference between useMemo and a normal calculation?
A normal calculation runs whenever the component renders.
const total = price * quantity;
With useMemo:
const total = useMemo(() => {
return price * quantity;
}, [price, quantity]);
useMemo allows React to reuse the cached result when its dependencies have not changed.
However, for a simple calculation such as multiplication, useMemo is usually unnecessary.
Use useMemo mainly when memoization provides a meaningful performance benefit.
10. Build a Practical Product Filter using useMemo
Create a product list where users can search products and filter them by category.
Solution:
import { useMemo, useState } from "react";
function ProductList() {
const [search, setSearch] = useState("");
const [category, setCategory] = useState("all");
const products = [
{ id: 1, name: "Laptop", category: "electronics" },
{ id: 2, name: "Mouse", category: "electronics" },
{ id: 3, name: "T-Shirt", category: "clothing" },
{ id: 4, name: "Shoes", category: "clothing" },
];
const filteredProducts = useMemo(() => {
return products.filter((product) => {
const matchesSearch = product.name
.toLowerCase()
.includes(search.toLowerCase());
const matchesCategory =
category === "all" || product.category === category;
return matchesSearch && matchesCategory;
});
}, [search, category]);
return (
<div>
<h1>Product Search</h1>
<input
type="text"
value={search}
onChange={(event) => setSearch(event.target.value)}
placeholder="Search product"
/>
<select
value={category}
onChange={(event) => setCategory(event.target.value)}
>
<option value="all">All</option>
<option value="electronics">Electronics</option>
<option value="clothing">Clothing</option>
</select>
{filteredProducts.length > 0 ? (
filteredProducts.map((product) => (
<p key={product.id}>
{product.name} - {product.category}
</p>
))
) : (
<p>No products found.</p>
)}
</div>
);
}
export default ProductList;
How it works:
searchstores the search text.categorystores the selected category.useMemocalculates the filtered product list.- The calculation depends on
searchandcategory. - When either value changes, the filtering calculation runs again.
- When unrelated state changes, React can reuse the memoized result if the dependencies remain unchanged.
This is a practical example of using useMemo for derived data.
Key Takeaways
useMemocaches the result of a calculation between renders.- It can help avoid unnecessary expensive calculations.
- The dependency array determines when the calculation needs to be recalculated.
useMemocan be useful for filtering, sorting, or other expensive derived data.- If a dependency changes, React recalculates the memoized value.
- If dependencies remain unchanged, React can reuse the cached result.
useMemois a performance optimization, not something every calculation needs.- Simple calculations usually do not need
useMemo. - The dependency list should include the reactive values used by the calculation.
useMemoreturns a value, whileuseCallbackis used to memoize a function.- Memoization should be used when it provides a meaningful benefit rather than automatically for every value.
FAQs
1. What is useMemo in React?
useMemo is a React Hook that caches the result of a calculation between renders.
2. Why do we use useMemo?
It can help avoid repeating expensive calculations when the values required for that calculation have not changed.
3. Does useMemo prevent component re-renders?
No. useMemo does not prevent a component from rendering. It memoizes the result of a calculation.
4. What is the dependency array in useMemo?
The dependency array contains the reactive values that the calculation depends on.
const result = useMemo(() => {
return calculate(data);
}, [data]);
5. When does useMemo recalculate its value?
It recalculates the value when one of its dependencies changes during a render.
6. Should I use useMemo for every calculation?
No. useMemo adds complexity and has its own overhead. It is most useful when avoiding a meaningful amount of repeated calculation provides a performance benefit.
7. What is the difference between useMemo and useCallback?
useMemo memoizes a calculated value, while useCallback memoizes a function reference.
Written by Shubhranshu Shekhar, who has trained 20000+ students in coding.
