useCallback in ReactJS
useCallback
is a hook in React that returns a memoized version of the callback function that only changes if one of the dependencies has changed. This is useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders.
Here’s a step-by-step guide on how to use useCallback
:
Basic Usage
Example: Preventing Unnecessary Re-renders
Suppose you have a parent component that passes a callback to a child component. Without useCallback
, the child component might re-render unnecessarily because the callback is recreated on every render.
import React, { useState, useCallback } from 'react';
const ChildComponent = React.memo(({ onClick }) => {
console.log('ChildComponent re-rendered');
return <button onClick={onClick}>Click me</button>;
});
const ParentComponent = () => {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
console.log('Button clicked');
}, []);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
<ChildComponent onClick={handleClick} />
</div>
);
};
export default ParentComponent;
In this example:
handleClick
is memoized usinguseCallback
so that it does not change on every render ofParentComponent
.ChildComponent
is wrapped withReact.memo
to prevent unnecessary re-renders when theonClick
prop remains the same.
When to Use useCallback
Use useCallback
when:
- You pass a callback function to a child component that relies on reference equality to prevent re-renders (e.g., when using
React.memo
). - The callback function is used in dependencies of other hooks (like
useEffect
,useMemo
, or otheruseCallback
hooks).
Detailed Breakdown
Example: Using useCallback
with useEffect
import React, { useState, useCallback, useEffect } from 'react';
const ParentComponent = () => {
const [count, setCount] = useState(0);
const [text, setText] = useState('');
const handleClick = useCallback(() => {
console.log('Button clicked');
}, []);
useEffect(() => {
console.log('Callback changed');
}, [handleClick]);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
<button onClick={handleClick}>Click me</button>
<input
type="text"
value={text}
onChange={(e) => setText(e.target.value)}
placeholder="Type something..."
/>
</div>
);
};
export default ParentComponent;
In this example:
handleItemClick
is memoized usinguseCallback
to preventList
from re-rendering unnecessarily.List
is wrapped withReact.memo
to optimize its rendering based on prop changes.
Summary
- Purpose:
useCallback
memoizes callback functions to prevent unnecessary re-creations on every render. - Usage: Use
useCallback
when passing callbacks to child components that rely on reference equality to prevent re-renders or when using callbacks as dependencies in other hooks. - Benefits: Optimizes performance by reducing unnecessary re-renders and re-computations.
By using useCallback
, you can make your React applications more efficient, especially when dealing with complex component trees and performance-sensitive operations.