JAVASCRIPT
Optimizing Performance with React's useMemo Hook
Discover how to prevent unnecessary re-renders of expensive computations in React components using the useMemo hook, significantly enhancing application performance.
import React, { useState, useMemo } from 'react';
// A simulated expensive computation
const calculateFactorial = (n) => {
console.log('Calculating factorial...');
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 PerformanceOptimizedComponent() {
const [number, setNumber] = useState(1);
const [darkTheme, setDarkTheme] = useState(false);
// useMemo will only re-run calculateFactorial if 'number' changes.
// If 'darkTheme' changes, this memoized value will not be recomputed.
const memoizedFactorial = useMemo(() => calculateFactorial(number), [number]);
const themeStyle = {
backgroundColor: darkTheme ? '#333' : '#eee',
color: darkTheme ? '#eee' : '#333',
padding: '20px',
borderRadius: '8px',
marginBottom: '10px'
};
return (
<div style={themeStyle}>
<h1>useMemo Performance Example</h1>
<input
type="number"
value={number}
onChange={(e) => setNumber(Number(e.target.value))}
style={{ marginBottom: '10px', padding: '8px' }}
/>
<p>Factorial of {number} is: {memoizedFactorial}</p>
<button
onClick={() => setDarkTheme(prevTheme => !prevTheme)}
style={{ padding: '10px', backgroundColor: '#007bff', color: 'white', border: 'none', borderRadius: '4px' }}
>
Toggle Theme
</button>
<p>Theme will toggle without re-calculating factorial unless number changes.</p>
</div>
);
}
How it works: The `useMemo` hook is used to memoize the result of an expensive computation. It takes a function and an array of dependencies. React will only re-execute the function and re-calculate the value if any of the dependencies in the array have changed since the last render. In this example, `memoizedFactorial` is only recalculated when the `number` state changes. Toggling the `darkTheme` state, which does not affect the `number`, will cause a re-render of the component but will use the cached `memoizedFactorial` value, preventing unnecessary, costly computations.