JAVASCRIPT
Memoizing Callback Functions with useCallback
Improve React component performance by using `useCallback` to memoize function references, preventing unnecessary re-renders of child components that depend on those functions.
import React, { useState, useCallback, memo } from 'react';
const Button = memo(({ onClick, children }) => {
console.log(`Rendering Button: ${children}`);
return <button onClick={onClick}>{children}</button>;
});
function ParentComponent() {
const [count, setCount] = useState(0);
const [otherState, setOtherState] = useState(0);
// This function reference will be stable across renders
const handleClick = useCallback(() => {
setCount((prevCount) => prevCount + 1);
}, []); // Empty dependency array means it's created once
// This function reference will change on every render
const handleOtherClick = () => {
setOtherState((prev) => prev + 1);
};
return (
<div>
<p>Count: {count}</p>
<Button onClick={handleClick}>Increment Count</Button>
<p>Other State: {otherState}</p>
{/*
This button will re-render even if otherState is the same,
because handleOtherClick is a new function on every render.
If it were a memoized child, it would cause unnecessary re-renders.
*/}
<Button onClick={handleOtherClick}>Increment Other State</Button>
<button onClick={() => setCount(count + 1)}>
Trigger Parent Rerender (for comparison)
</button>
</div>
);
}
How it works: This example illustrates `useCallback`'s role in performance optimization. When a function is passed as a prop to a memoized child component (like `Button` wrapped with `memo`), `useCallback` ensures that the function's reference remains stable across parent component re-renders. This prevents the child component from re-rendering unnecessarily because of a new function reference, even if its actual logic hasn't changed, thus enhancing overall application performance.