JAVASCRIPT
Optimizing Expensive Computations with useMemo
Use the React useMemo hook to memoize and cache the results of expensive calculations, preventing unnecessary re-renders and boosting performance in your components.
import React, { useState, useMemo } from 'react';
// Simulate an expensive calculation
const calculateFactorial = (n) => {
console.log(`Calculating factorial for ${n}...`);
if (n < 0) return -1;
if (n === 0) return 1;
let result = 1;
for (let i = 1; i <= n; i++) {
result *= i;
// Simulate heavy computation
let j = 0;
while (j < 10000000) { j++; }
}
return result;
};
function FactorialCalculator() {
const [number, setNumber] = useState(1);
const [incrementer, setIncrementer] = useState(0);
// Without useMemo, this calculation would run on every re-render (e.g., when incrementer changes)
// const factorial = calculateFactorial(number);
// With useMemo, calculation only runs when 'number' changes
const factorial = useMemo(() => calculateFactorial(number), [number]);
return (
<div style={{ padding: '20px', border: '1px solid #ccc', borderRadius: '8px', maxWidth: '400px', margin: '20px auto' }}>
<h1>Factorial Calculator</h1>
<div>
<label>
Number:
<input
type="number"
value={number}
onChange={(e) => setNumber(parseInt(e.target.value, 10))}
/>
</label>
<p>Factorial of {number} is: {factorial}</p>
</div>
<hr />
<div>
<p>Independent State: {incrementer}</p>
<button onClick={() => setIncrementer(prev => prev + 1)}>
Increment Independent State
</button>
<p style={{ fontSize: '0.8em', color: '#666' }}>
Observe console logs. Factorial calculation only runs when "Number" changes, not when "Independent State" changes.
</p>
</div>
</div>
);
}
// To use, render <FactorialCalculator /> in your App component.
How it works: This snippet illustrates the `useMemo` hook, which optimizes performance by memoizing (caching) the result of an expensive function. The `calculateFactorial` function, simulated as costly, will only re-execute when its dependencies (in this case, `number`) change. This prevents unnecessary re-calculations during component re-renders triggered by unrelated state changes (like `incrementer`), significantly improving application responsiveness and efficiency.