JAVASCRIPT
Memoize Functions to Prevent Unnecessary Re-renders with useCallback
Discover how React's useCallback hook optimizes performance by memoizing functions, preventing unnecessary re-creation and re-renders in child components.
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);
const [input, setInput] = useState('');
// Without useCallback, handleClick would be recreated on every ParentComponent re-render,
// causing ChildComponent to re-render even if its props haven't conceptually changed.
const handleClick = useCallback(() => {
setCount(prevCount => prevCount + 1);
console.log('Button clicked, count:', count + 1);
}, [count]); // Dependency array: recreate handleClick if count changes
return (
<div>
<h2>useCallback Example</h2>
<p>Parent Count: {count}</p>
<input
type="text"
value={input}
onChange={(e) => setInput(e.target.value)}
placeholder="Type here to trigger Parent re-render"
/>
<ChildComponent onClick={handleClick} />
<p>Input Value: {input}</p>
</div>
);
}
export default ParentComponent;
How it works: The `useCallback` hook memoizes a function. It returns a memoized version of the callback that only changes if one of the dependencies has changed. This is particularly useful when passing callbacks to optimized child components (like `React.memo` or `PureComponent`) to prevent them from re-rendering unnecessarily due to the parent component creating a new function instance on every render.