JAVASCRIPT
Optimize Event Handlers with useCallback to Prevent Unnecessary Rerenders
Understand how to use the `useCallback` hook in React to memoize function definitions, preventing child components from re-rendering due to new function instances.
import React, { useState, useCallback } from 'react';
const ChildComponent = React.memo(({ onClick }) => {
console.log('ChildComponent rendered');
return <button onClick={onClick}>Click Me (Child)</button>;
});
function ParentComponent() {
const [count, setCount] = useState(0);
// Without useCallback, this function would be recreated on every ParentComponent render
// With useCallback, it's memoized as long as count doesn't change
const handleClick = useCallback(() => {
setCount(prevCount => prevCount + 1);
console.log('Button clicked!');
}, []); // Dependency array: empty because handleClick doesn't depend on `count` directly
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment Parent Count</button>
<ChildComponent onClick={handleClick} />
</div>
);
}
export default ParentComponent;
How it works: The `ChildComponent` is wrapped with `React.memo` to prevent re-renders if its props haven't changed. In `ParentComponent`, `handleClick` is wrapped with `useCallback`. This ensures that the `handleClick` function instance remains the same across re-renders of `ParentComponent`, as long as its dependencies (none in this case, as `setCount` is stable) don't change. This prevents `ChildComponent` from re-rendering when `ParentComponent` updates other state (like `count`), because the `onClick` prop remains referentially equal.