useCallback vs useMemo in React
Expert-Level Explanation
useCallback
and useMemo
are hooks used for performance optimisation, but they serve different purposes.
useCallback
This hook returns a memoized callback function. It ensures that the function instance remains the same across renders unless its dependencies change. This is particularly useful when passing callbacks to optimised child components that rely on reference equality to prevent unnecessary renders.useMemo
On the other hand,useMemo
returns a memoized value. It’s used to perform expensive calculations and recompute them only when one of the specified dependencies has changed. This helps in avoiding costly recalculations on each render.
Creative Explanation
Imagine useCallback
as a personal trainer who plans your workout routine (a function). Even if you go to the gym (re-render the component) multiple times, the trainer gives you the same routine, unless your fitness goals (dependencies) change.
useMemo
is like a meal prep service. They prepare your meals (calculate a value) for the week and only change the menu (recompute the value) if your dietary preferences (dependencies) change.
Practical Explanation with Code
Using useCallback
:
import React, { useCallback, useState } from 'react';
function MyComponent({ onButtonClick }) {
const [count, setCount] = useState(0);
const increment = useCallback(() => {
setCount(c => c + 1);
}, []);
return <button onClick={increment}>Clicked {count} times</button>;
}
Using useMemo
:
import React, { useMemo, useState } from 'react';
function ExpensiveComponent({ list }) {
const sortedList = useMemo(() => {
return list.sort((a, b) => a - b);
}, [list]);
return sortedList.map(item => <div key={item}>{item}</div>);
}
Real-World Example
In a web application with a search feature,useCallback
can be used for the search input's change handler. This ensures that the handler function doesn't change between renders unless necessary, preventing unnecessary re-renders of components that use the handler as a prop.
For exampleuseMemo
, consider a financial dashboard that displays a list of transactions. Calculating the total balance might be a costly operation if the list is large. By usinguseMemo
, this calculation would only be re-performed when the list of transactions changes, thus improving performance.