JAVASCRIPT
Optimize Performance with useCallback for Event Handlers
Learn how to use React's `useCallback` hook to memoize event handler functions, preventing unnecessary re-renders of child components when props change.
import React, { useState, useCallback } from 'react';
// A child component that re-renders only if its props change
const Button = React.memo(({ onClick, children }) => {
console.log(`Rendering Button: ${children}`);
return <button onClick={onClick}>{children}</button>;
});
function ParentComponent() {
const [count, setCount] = useState(0);
const [text, setText] = useState('');
// Without useCallback, handleClick would be recreated on every render of ParentComponent,
// causing Button to re-render even if its content/logic hasn't changed.
const handleClick = useCallback(() => {
setCount((prevCount) => prevCount + 1);
}, []); // Empty dependency array means this function is created once
const handleTextChange = useCallback((e) => {
setText(e.target.value);
}, []); // Empty dependency array means this function is created once
return (
<div>
<h1>Count: {count}</h1>
<Button onClick={handleClick}>Increment Count</Button>
<br />
<input type="text" value={text} onChange={handleTextChange} placeholder="Type something..." />
<p>Input Text: {text}</p>
</div>
);
}
export default ParentComponent;
How it works: This snippet illustrates how `useCallback` can optimize React components. By wrapping the `handleClick` and `handleTextChange` functions with `useCallback` and providing an empty dependency array `[]`, these functions are memoized. They will only be re-created if their dependencies change. When passed as props to a `React.memo`'d child component like `Button`, this prevents the child component from re-rendering unnecessarily when the parent component re-renders but the handler function reference hasn't changed, thus improving performance.