JAVASCRIPT
Optimize React Performance with useCallback Hook
Discover how to prevent unnecessary re-renders in child components by memoizing callback functions with the React useCallback hook for performance optimization.
import React, { useState, useCallback } from 'react';
function Button({ onClick, children }) {
console.log(`Rendering button for: ${children}`);
return <button onClick={onClick}>{children}</button>;
}
// Memoize the Button component itself to demonstrate useCallback's effect
const MemoizedButton = React.memo(Button);
function ParentComponent() {
const [count, setCount] = useState(0);
const [anotherState, setAnotherState] = useState(0);
// This function will only be re-created if its dependencies change. Here, no dependencies.
const handleClick = useCallback(() => {
setCount(prevCount => prevCount + 1);
}, []);
// This function will only be re-created if 'anotherState' changes
const handleAnotherClick = useCallback(() => {
setAnotherState(prev => prev + 1);
}, [anotherState]);
return (
<div>
<p>Count: {count}</p>
<p>Another State: {anotherState}</p>
<MemoizedButton onClick={handleClick}>Increment Count</MemoizedButton>
<MemoizedButton onClick={handleAnotherClick}>Increment Another State</MemoizedButton>
<button onClick={() => setCount(count + 1)}>Force Parent Re-render (without changing state for handleClick)</button>
</div>
);
}
export default ParentComponent;
How it works: The useCallback hook returns a memoized version of the callback function that only changes if one of the dependencies has changed. This is particularly useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders (e.g., components wrapped in React.memo). By memoizing the callback, you ensure that the child component does not re-render merely because the parent component re-rendered and created a new function instance.