JAVASCRIPT
Memoize Expensive Calculations with useMemo
Improve React application performance by using the `useMemo` hook to memoize the results of expensive computations, re-calculating only when dependencies change.
import React, { useState, useMemo } from 'react';
// A computationally expensive function
const calculateFactorial = (n) => {
console.log('Calculating factorial...'); // Simulate expensive calculation
if (n < 0) return -1;
if (n === 0) return 1;
let result = 1;
for (let i = 1; i <= n; i++) {
result *= i;
}
return result;
};
function FactorialCalculator() {
const [number, setNumber] = useState(1);
const [theme, setTheme] = useState('light');
// useMemo will only re-run calculateFactorial if 'number' changes.
// If 'theme' changes, factorialValue will use the memoized result.
const factorialValue = useMemo(() => calculateFactorial(number), [number]);
const handleNumberChange = (e) => {
const value = parseInt(e.target.value, 10);
setNumber(isNaN(value) ? 1 : value);
};
const toggleTheme = () => {
setTheme((prevTheme) => (prevTheme === 'light' ? 'dark' : 'light'));
};
const themeStyle = {
background: theme === 'dark' ? '#333' : '#FFF',
color: theme === 'dark' ? '#FFF' : '#333',
padding: '20px',
minHeight: '100px'
};
return (
<div style={themeStyle}>
<h2>Factorial Calculator</h2>
<div>
<label>Enter a number:</label>
<input type='number' value={number} onChange={handleNumberChange} min='0' />
</div>
<p>Factorial of {number} is: {factorialValue}</p>
<button onClick={toggleTheme}>Toggle Theme ({theme})</button>
<p>Note: Check console for 'Calculating factorial...' messages.</p>
</div>
);
}
export default FactorialCalculator;
How it works: The `useMemo` hook is used to memoize the result of an expensive calculation, preventing it from being re-computed on every render. The provided function runs only when its dependencies (defined in the second argument array) change. In this example, `calculateFactorial` is an expensive operation. By wrapping it in `useMemo`, `factorialValue` will only be recalculated if the `number` state changes. Changes to other states, like `theme`, will not trigger a re-calculation, thus improving performance by avoiding unnecessary computations.