JAVASCRIPT
Memoize Expensive Computations with useMemo
Boost React performance with `useMemo`. Cache results of expensive computations or object creations, preventing re-computation on every render for efficiency.
import React, { useState, useMemo } from 'react';
function ExpensiveCalculationComponent() {
const [number, setNumber] = useState(1);
const [multiplier, setMultiplier] = useState(1);
const [renderCount, setRenderCount] = useState(0);
// Simulate an expensive computation
const calculateFactorial = (num) => {
console.log('Calculating factorial...');
if (num < 0) return -1;
if (num === 0) return 1;
let result = 1;
for (let i = 1; i <= num; i++) {
result *= i;
}
return result;
};
// Memoize the factorial calculation.
// It will only re-run if 'number' changes.
const memoizedFactorial = useMemo(() => {
return calculateFactorial(number);
}, [number]);
// This object will be recreated on every render without useMemo,
// potentially causing issues for child components that memoize props.
// With useMemo, it's only recreated if number or multiplier changes.
const memoizedConfig = useMemo(() => ({
value: number * multiplier,
type: 'product'
}), [number, multiplier]);
return (
<div>
<p>Component Render Count: {renderCount}</p>
<button onClick={() => setRenderCount(prev => prev + 1)}>Force Re-render</button>
<hr />
<label>Number:
<input
type="number"
value={number}
onChange={(e) => setNumber(parseInt(e.target.value) || 0)}
/>
</label>
<p>Factorial of {number} (memoized): {memoizedFactorial}</p>
<hr />
<label>Multiplier:
<input
type="number"
value={multiplier}
onChange={(e) => setMultiplier(parseInt(e.target.value) || 0)}
/>
</label>
<p>Memoized Config Value: {memoizedConfig.value}</p>
<p>Memoized Config Type: {memoizedConfig.type}</p>
</div>
);
}
export default ExpensiveCalculationComponent;
How it works: The `useMemo` hook is used here to prevent expensive computations or object creations from running on every component render. `memoizedFactorial` will only recalculate `calculateFactorial(number)` if the `number` dependency changes. Similarly, `memoizedConfig` will only create a new object if `number` or `multiplier` changes. This ensures that the component only re-computes these values when necessary, leading to better performance, especially when dealing with complex logic or passing objects/arrays to memoized child components.