Sitemap
Stackademic

Stackademic is a learning hub for programmers, devs, coders, and engineers. Our goal is to democratize free coding education for the world.

Understanding the Real Cost of useCallback in React’s Rendering Model

--

The first question that usually comes to mind about useCallback() is: What exactly is useCallback()?

Press enter or click to view image in full size

We know that useCallback() is a React Hook used to optimize React applications. But this naturally leads to the next question: Does it actually optimize our app? If yes, how does it work under the hood?

Let’s explore how it works behind the scenes:

Most developers think useCallback = performance optimization.

But in many real-world cases, useCallback can actually make performance worse.

Let’s break it down deeply.

1. What useCallback Actually Does ->

const memoizedFun = useCallback (()=>{
doSomething(a,b)
},[a,b]);

Internally React does something like:

React keeps a hook list per component (ordered by call index)

[{
memoizedState: {
callBack: memoizedFun;
dep: [a, b]
}
}]

When component render First Time on the screen internally React store the memoizedFun function and store the dependency array.

if (arrDepEqual(prevDeps, currentDeps)) {
return prevCallback;
} else {
store new callBack and deps
return new callBack
}

When component render Second Time on the screen internally React compares the previous dependency with current dependance array if value of dependency is changed then it create a new function and store it at a place of momoizedFun and then return a new function reference but if the value of dependency array is same then it will return previous function reference.

Important: It does NOT stop function creation.

The function is still created on every render.
React just decides whether to return the old one.

2. Why It Can Be Harmful ->

Extra memory usage & Increased comparison cost

Get Arbaz khan’s stories in your inbox

Join Medium for free to get updates from this writer.

Each useCallback:

  • Stores function reference
  • Stores dependency array
  • Comparison dependencies on every render

If you as a senior developer wrap everything in useCallback, then you’re

  • Increasing memory usage
  • Increasing comparison work
  • Increasing React bookkeeping

For small components → this overhead is often more expensive than recreating the function.

3. Let’s now explore when useCallback() is truly beneficial and how to use it effectively:-

useCallback Solves Only One Problem (Reference Equality)

  • useCallback only help when
    - Passing function to a React.memo child
    - That child depends on function reference equality

If you’re not using React.memo, useCallback is useless.

const handleClick = useCallback(() => {
setCount(c => c + 1);
}, []);

<Child onClick={handleClick} />

If Child is not memorized → it re-renders anyway.

So useCallback did nothing.

const Child = React.memo(({ onClick }) => {
console.log("Child render");
return <button onClick={onClick}>Click</button>;
});

Important Note:

  • Creating a function in JS is extremely cheap.
  • Re-rendering a complex tree is expensive.
  • Developers often optimize the wrong thing.

--

--

Stackademic
Stackademic

Published in Stackademic

Stackademic is a learning hub for programmers, devs, coders, and engineers. Our goal is to democratize free coding education for the world.