Caches a function definition between re-renders. Essential for optimizing performance and preventing unnecessary child updates.
Passing an inline function to a memoized child component defeats the purpose of React.memo.
import { useState, memo } from 'react';
// Child is memoized, but it won't help!
const Child = memo(({ onClick }) => {
console.log("Child render");
return <button onClick={onClick}>Click me</button>;
});
function Parent() {
const [text, setText] = useState("");
// 🔴 PROBLEM: This function is re-created every render.
// So 'onClick' prop is always "new".
const handleClick = () => {
console.log("Clicked");
};
return (
<>
<input value={text} onChange={e => setText(e.target.value)} />
<Child onClick={handleClick} />
</>
);
}Wrap the handler in useCallback. Now the function reference is stable, and the child can skip re-rendering.
import { useState, useCallback, memo } from 'react';
const Child = memo(({ onClick }) => {
console.log("Child render - Optimized!");
return <button onClick={onClick}>Click me</button>;
});
function Parent() {
const [text, setText] = useState("");
// ✅ SOLUTION: Stable reference across renders
const handleClick = useCallback(() => {
console.log("Clicked");
}, []); // No dependencies, never changes!
return (
<>
<input value={text} onChange={e => setText(e.target.value)} />
<Child onClick={handleClick} />
</>
);
}