[React.js] - Part 15. React Hooks - useMemo Hook

Ace Lennox
The useMemo
Hook in React helps optimize performance by memoizing values. This means it caches a computed value and only recalculates it when its dependencies change. This guide will walk you through how to use the useMemo
Hook with clear examples and practical use cases.
What is useMemo
?
The useMemo
Hook is used to memoize the result of a computationally expensive function. By caching the result, React avoids unnecessary recalculations during renders.
Key Features of useMemo
:
Performance Optimization: Prevents unnecessary recalculations for expensive operations.
Dependencies: The function only re-runs when dependencies change.
Comparison to
useCallback
: WhileuseCallback
memoizes functions,useMemo
memoizes values.
Problem: Expensive Computations
Imagine you have an app with a computationally intensive function that runs on every render. Here’s an example:
Example: Without useMemo
import { useState } from "react";
import ReactDOM from "react-dom/client";
const App = () => {
const [count, setCount] = useState(0);
const [tasks, setTasks] = useState([]);
const heavyComputation = (num) => {
console.log("Running heavy computation...");
let result = 0;
for (let i = 0; i < 1000000000; i++) {
result += num;
}
return result;
};
const result = heavyComputation(count);
const increment = () => setCount((c) => c + 1);
const addTask = () => setTasks((prev) => [...prev, `Task ${prev.length + 1}`]);
return (
<div>
<h2>Tasks</h2>
{tasks.map((task, index) => (
<p key={index}>{task}</p>
))}
<button onClick={addTask}>Add Task</button>
<hr />
<h2>Count: {count}</h2>
<button onClick={increment}>Increment</button>
<h3>Computation Result: {result}</h3>
</div>
);
};
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
Problem: Poor Performance
Every time you add a task or increment the counter, the heavyComputation
function runs, even when it’s unnecessary. This causes a noticeable delay.
Solution: Using useMemo
By wrapping the computation in useMemo
, we ensure it only recalculates when the relevant dependency (count
) changes.
Example: Optimized with useMemo
import { useState, useMemo } from "react";
import ReactDOM from "react-dom/client";
const App = () => {
const [count, setCount] = useState(0);
const [tasks, setTasks] = useState([]);
const heavyComputation = (num) => {
console.log("Running heavy computation...");
let result = 0;
for (let i = 0; i < 1000000000; i++) {
result += num;
}
return result;
};
const result = useMemo(() => heavyComputation(count), [count]);
const increment = () => setCount((c) => c + 1);
const addTask = () => setTasks((prev) => [...prev, `Task ${prev.length + 1}`]);
return (
<div>
<h2>Tasks</h2>
{tasks.map((task, index) => (
<p key={index}>{task}</p>
))}
<button onClick={addTask}>Add Task</button>
<hr />
<h2>Count: {count}</h2>
<button onClick={increment}>Increment</button>
<h3>Computation Result: {result}</h3>
</div>
);
};
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
Why This Works
The
useMemo
Hook memoizes the result ofheavyComputation
.The function only re-runs when
count
changes, saving resources when tasks are added.
When to Use useMemo
Expensive Computations: Use
useMemo
for functions that require significant processing power.Frequent Renders: Optimize components that render often but don’t always need recalculations.
Complex Calculations: Cache derived values from state or props to avoid unnecessary processing.
Best Practices
Avoid Overusing
useMemo
: Only use it for performance-critical computations. Adding unnecessary memoization can complicate your code.Understand Dependencies: Ensure all values used inside the memoized function are included in the dependency array.
Debugging: Log statements like
console.log
can help you confirm when a function re-runs.
Conclusion
The useMemo
Hook is a valuable tool for optimizing React applications, especially for expensive computations. By memoizing results, you can improve performance and provide a smoother user experience.
Experiment with the examples above and see how useMemo
can make your React applications faster and more efficient!
Source Code
The complete source code for this part is available on GitHub