Every time a React component re-renders, functions declared inside its body are recreated as new objects in memory. useCallback caches a function definition between renders so its reference stays identical unless one of its listed dependencies changes.
useCallbackReact.memo Children: If a parent re-renders and passes an inline handler to a memoized child, the child re-renders anyway because the function reference changed. Wrapping the handler in useCallback keeps the child memoization working.useEffect Dependency: If an effect calls a helper function defined inside the component, caching that helper with useCallback avoids re-running the effect on unrelated state updates.import { memo, useCallback, useState } from 'react';
const FilterButton = memo(function FilterButton({ label, onSelect }) {
return (
<button type="button" onClick={() => onSelect(label)}>
{label}
</button>
);
});
export function IssueTracker() {
const [search, setSearch] = useState('');
const [activeFilter, setActiveFilter] = useState('open');
const handleSelect = useCallback((filterName) => {
setActiveFilter(filterName);
}, []);
return (
<div>
<input value={search} onChange={(e) => setSearch(e.target.value)} />
<p>Filter: {activeFilter}</p>
<FilterButton label="open" onSelect={handleSelect} />
<FilterButton label="closed" onSelect={handleSelect} />
</div>
);
}
Because handleSelect calls setActiveFilter(filterName) without reading activeFilter, its dependency array stays empty ([]). Whenever possible, use functional state setters (setItems(prev => ...)) inside useCallback so the callback rarely needs to be recreated.
useCallback MistakesuseCallback Without React.memo or useEffect: Wrapping a click handler on a plain <button> adds memory overhead with zero speedup because <button> is not memoized.useCallback and useMemo?useCallback(fn, deps) caches the function fn itself so you can call it later. useMemo(() => value, deps) calls the function immediately and caches its return value.
useCallback prevent the function from being created in JS syntax?JavaScript still allocates the inline function argument during render, and useCallback simply returns the previously saved reference when dependencies match.
useCallback?When using React 19's React Compiler, build-time memoization stabilizes callbacks automatically, though knowing useCallback remains essential for reading and tuning manual React code.
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With
You've completed this section! Take a quick 5-question quiz to check your understanding.