useMemo
is used to memoize the result of a computation, so the computation is only performed when its dependencies change. This can improve performance by avoiding expensive calculations on every render.
useMemo
:Expensive Calculations:
Use useMemo
when you have a computationally expensive function that returns a value. Memoizing the result ensures that the calculation only runs when its dependencies change, rather than on every render.
Example:
const expensiveCalculation = useMemo(() => {
return computeExpensiveValue(a, b);
}, [a, b]);
Dependent Values:
When you have values that are derived from props or state and are used in rendering, memoize them to prevent unnecessary recalculations.
Example:
const derivedValue = useMemo(() => {
return someCalculation(props.value);
}, [props.value]);
Avoiding Recalculations in List Rendering:
When rendering a list where each item requires some derived data, memoize the derived data to avoid recalculating it for each render.
Example:
const itemsWithComputedProps = useMemo(() => {
return items.map(item => ({ ...item, computedProp: computeProp(item) }));
}, [items]);
useMemo
:useMemo
might not be worth it.useMemo
is unnecessary.useCallback
is used to memoize callback functions, ensuring the function reference remains the same between renders unless its dependencies change. This is particularly useful for preventing unnecessary re-renders of child components that rely on these functions.
useCallback
:Event Handlers:
Use useCallback
for event handlers passed down to child components to prevent unnecessary re-renders of those components.
Example:
const handleClick = useCallback(() => {
console.log('Clicked');
}, []);
Optimising Performance in Child Components:
When a child component depends on a callback function and uses React.memo
for optimisation, use useCallback
to ensure the function reference doesn't change on every render.
Example:
const handleChange = useCallback((event) => {
setValue(event.target.value);
}, []);
return <InputComponent onChange={handleChange} />;
Avoiding Function Recreation:
When a function is used inside a dependency array of useEffect
, useMemo
, or another useCallback
, memoize it to prevent unnecessary recreation of the function.
Example:
const fetchData = useCallback(() => {
// Fetch data logic
}, [dependency]);
useEffect(() => {
fetchData();
}, [fetchData]);
useCallback
:Inline Handlers for Simple Elements:
For simple inline event handlers directly on JSX elements, useCallback
might be overkill.
Example:
<button onClick={() => setClicked(true)}>Click me</button>
Non-Performance Critical Code:
useCallback
unnecessarily can add complexity without benefits.