When to use useCallback() hook

When to use useCallback() hook

useCallback hook is something very controversial, understand and learn when to use it.

One can easily classify a bunch of react devs into two groups based on their useCallback() usage.

  • those who use it for every inline function in a component and memoize.
  • those who only use it only when needed and optimize performance.

Let's understand what really is this native hook and when to use it.

What is useCallback hook?

The useCallback is a native hook provided by React that returns a memoized callback function(Think of memoization as caching a value so that it does not need to be recalculated).

Why do we need useCallback hook?

React by itself does a lot of optimizations but why it has another API to handle optimizations by devs? To understand the above statement, we must first know the important fundamental JavaScript concept that will make understanding useCallback easier—object references

Object references

Functions in JavaScript are first-class citizens, meaning that a function is a regular object. The function object can be returned by other functions, be compared, etc. Even if two functions are identical, they won't equal each other.

Let's write a simple function add() that returns functions that add numbers:

function add() {
  return (a, b) => a + b;
}
const add1 = add();
const add2 = add();
add1(1, 2); // => 3
add2(1, 2); // => 3
add1 === add2; // => false
add1 === add1; // => true

The functions add1 and add2 share the same code source but they are different function objects. Comparing them add1 === add2 evaluates to false.

That's just how JavaScript objects work. An object (including a function object) equals only itself.

When should we use useCallback hook?

The reason for explaining object reference is whenever a component re-renders in React, all inline functions in the component get recreated. Now imagine if the inline function does heavy calculations, it would be a waste of CPU cycles if the values/params of the inline function are the same as the previous render.

In most use cases, your application won't be affected if a function is re-created and gets a new object reference upon each render. Even so, it can be tempting to proactively wrap a function in a useCallback to improve app performance. However, this premature optimization can actually do harm rather than good. A blog post by Kent Dodds explains when and when not to use useCallback.

A good way to approach using useCallback is reactively rather than proactively. This means that, depending on your components, use it when you obviously need to, and not as a premature performance optimization. In short, don't wrap every function living inside a function body in a useCallback.

It's highly recommended that you have React linting in your development environment so that your linter can suggest appropriate times to use useCallback.

If your linter is not suggesting useCallback, but you see that your UI is re-rendering in unexpected ways, or you have an infinite loop, check to see whether useCallback helps.

Thanks for reading..!