What is useCallback in React?
Learn what useCallback does in React, how it memoizes function references, why it pairs with React.memo, and when it actually improves performance.
Expected Interview Answer
useCallback is a React hook that returns a memoized version of a function, keeping the same function reference across renders as long as its dependencies don't change, which is useful when passing callbacks to memoized child components or effects.
Every time a component re-renders, any function defined inside it is recreated as a brand-new reference by default, even if its logic is identical. useCallback(fn, deps) returns the same function instance between renders as long as the values in the dependency array haven't changed, preventing that unnecessary recreation. This matters most when the function is passed as a prop to a child wrapped in React.memo, since a new function reference would otherwise defeat the memoization and cause the child to re-render regardless. It also matters when a function is listed as a dependency of useEffect or useMemo, since a stable reference avoids re-running that effect on every render. useCallback is essentially useMemo specialized for caching functions rather than arbitrary values.
- Keeps a stable function reference across renders
- Preserves React.memo optimization on child components
- Prevents unnecessary effect re-runs when a function is a dependency
- Reduces unnecessary garbage collection of throwaway functions
- Complements useMemo for a consistent memoization strategy
AI Mentor Explanation
useCallback is like a bowler keeping the exact same run-up and grip for a signature delivery every over, instead of re-learning a fresh grip from scratch each time they walk back to their mark. The batter recognizes that familiar, unchanged delivery and reacts consistently, rather than having to reassess a brand-new action every single ball.
Step-by-Step Explanation
Step 1
Identify a recreated function
Spot a function defined inside a component that gets passed down as a prop to a child.
Step 2
Import useCallback
Import useCallback from 'react' in the component file.
Step 3
Wrap the function
Call useCallback(fn, [dependencies]) to memoize the function reference.
Step 4
List accurate dependencies
Include every value the function reads from the outer scope so it updates correctly.
Step 5
Pair with React.memo
Wrap the receiving child in React.memo so the stable reference actually prevents unnecessary re-renders.
What Interviewer Expects
- Explains useCallback memoizes a function reference, not its result
- Knows it's most valuable with React.memo children or effect dependencies
- Understands the dependency array controls when a new function is created
- Can relate useCallback to useMemo conceptually
- Warns against overusing it where no memoized child depends on it
Common Mistakes
- Using useCallback everywhere without a memoized consumer benefiting from it
- Forgetting dependencies, causing the callback to close over stale values
- Confusing useCallback's memoized function with useMemo's memoized value
- Assuming useCallback prevents the component itself from re-rendering
- Not pairing useCallback with React.memo, losing its intended benefit
Best Answer (HR Friendly)
“useCallback keeps a function from being recreated every time a component updates, so that other parts of the app relying on that exact function don't refresh unnecessarily. It's a small performance tool mainly useful when passing functions down to specially optimized child components.”
Code Example
import { useState, useCallback, memo } from 'react';
const ExpensiveButton = memo(function ExpensiveButton({ onClick }) {
console.log('ExpensiveButton rendered');
return <button onClick={onClick}>Click me</button>;
});
function Parent() {
const [count, setCount] = useState(0);
const [text, setText] = useState('');
// Stable reference: only changes if its dependencies change (none here)
const handleClick = useCallback(() => {
setCount((c) => c + 1);
}, []);
return (
<div>
<input value={text} onChange={(e) => setText(e.target.value)} />
<p>Count: {count}</p>
<ExpensiveButton onClick={handleClick} />
</div>
);
}Follow-up Questions
- How does useCallback relate to useMemo?
- Why does useCallback matter for components wrapped in React.memo?
- What happens if you omit a dependency used inside the callback?
- Can useCallback improve performance without React.memo on the child?
- When is useCallback unnecessary overhead?
MCQ Practice
1. What does useCallback memoize?
useCallback returns a memoized function reference, keeping it stable across renders when dependencies don't change.
2. useCallback is most beneficial when paired with which pattern?
A stable function reference from useCallback preserves React.memo's optimization on children that receive it as a prop.
3. How is useCallback related to useMemo?
useCallback(fn, deps) behaves like useMemo(() => fn, deps), memoizing a function specifically rather than any value.
Flash Cards
What does useCallback return? — A memoized function reference that stays stable across renders unless its dependencies change.
When is useCallback most useful? — When passing a function to a React.memo child or listing it as an effect dependency.
How does useCallback relate to useMemo? — It's effectively useMemo specialized for memoizing functions instead of general values.
Does useCallback alone guarantee fewer re-renders? — No — it only helps if paired with React.memo or a dependency check that benefits from a stable reference.