Skip to main content

What does useCallback() do?

What does useCallback() do

useCallback() is a hook that memoizes the function itself, that is, it keeps its reference between renders, so that React doesn't create a new function every time if its dependencies haven't changed.


Syntax

javascript
const memoizedCallback = useCallback(() => { // function code }, [dependencies]);
  • The first argument is the function to "remember".
  • The second argument is the dependency array. As long as the dependencies don't change, React will return the same function.

Example without useCallback (not optimized)

javascript
function App() { const [count, setCount] = useState(0); // A new function is created on every render const handleClick = () => { setCount(count + 1); }; return <Button onClick={handleClick} />; }

If Button is wrapped in React.memo, it will still re-render, because handleClick is a new reference every time.


Example with useCallback (optimized)

javascript
import { useState, useCallback } from "react"; function App() { const [count, setCount] = useState(0); // The function is recreated only when count changes const handleClick = useCallback(() => { setCount(c => c + 1); }, []); return <Button onClick={handleClick} />; } const Button = React.memo(({ onClick }) => { console.log("Button re-render"); return <button onClick={onClick}>+</button>; });

Now handleClick doesn't change its reference on every render, and React.memo(Button) doesn't re-render without a reason.


What useCallback() returns

useCallback() returns the same function you passed it, but memoized (with a preserved reference).

Put simply:

javascript
useCallback(fn, deps)

is equivalent to:

javascript
useMemo(() => fn, deps)

When useCallback() is useful

SituationWhy use it
You pass functions to child componentsTo avoid causing them an unnecessary re-render
You use useEffect or useMemo and want a stable dependencySo the effect doesn't fire every time
In components where a handler is created inside JSXTo avoid recreating the function on every render

Example: stabilizing a dependency in useEffect

javascript
function Example({ userId }) { const fetchUser = useCallback(() => { return fetch(`/api/user/${userId}`).then(r => r.json()); }, [userId]); useEffect(() => { fetchUser().then(console.log); }, [fetchUser]); // doesn't trigger an infinite loop }

Without useCallback, fetchUser would be created every time, and useEffect would fire infinitely.


Important to remember

RuleExplanation
useCallback doesn't speed up the code itselfIt only prevents unnecessary re-renders
Don't use it everywhereOnly if the function is passed as a prop or used in dependencies
Works by referenceReact compares not the content of the function but its reference in memory

Summary

QuestionAnswer
What does useCallback() doMemoizes (caches) a function so it isn't recreated on every render
When is it recreatedOnly if the dependencies change
What it returnsA stable (the same) reference to the function
When to use itWhen the function is passed to a child component or used in useEffect
When not neededIf the function doesn't affect re-renders or isn't used as a dependency

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.