useCallback hook and functions equality check problem

41 Views Asked by At

Trying to understand the useCallback() hook in react. In a blog post someone said that it solves the following problem:

Before diving into useCallback() use, let's distinguish the problem useCallback() solves — the functions equality check.

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.: anything you can do with an object.

Let's write a function factory() that returns functions that sum numbers:

function factory() {
  return (a, b) => a + b;
}

const sumFunc1 = factory();
const sumFunc2 = factory();

console.log(sumFunc1(1, 2)); // => 3
console.log(sumFunc2(1, 2)); // => 3

console.log(sumFunc1 === sumFunc2); // => false
console.log(sumFunc1 === sumFunc1); // => true

sumFunc1 and sumFunc2 are functions that sum two numbers. They've been created by the factory() function.

The functions sumFunc1 and sumFunc2 share the same code source, but they are different >function objects. Comparing them sumFunc1 === sumFunc2 evaluates to false.

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

So my questions:

  1. How sumFunc1 === sumFunc2 returns false
  2. How the useCallback() hook solves that
  3. How useCallback() hook is actually used for memoization?
1

There are 1 best solutions below

0
Ben On

I think the latest version of the React documentation on the useCallback hook answers all three of your questions.

  1. How sumFunc1 === sumFunc2 returns false?

"In JavaScript, a function () {} or () => {} always creates a different function, similar to how the {} object literal always creates a new object" - from the docs. Expanding a bit more on that, in JS, functions are objects and they refer to specific blocks in memory. So when you create a new function, you essentially create a new object that points to a new block of memory. This answer by Karol expands even further on this with the actual specification.

  1. How the useCallback() hook solves that?

Instead of recreating the function on re-render, the hook caches your function until its dependencies change. They have a great, interactive example in the docs.

  1. How useCallback() hook is actually used for memoization?

It's used as wrapper for a function that you want to preserve, or more precisely, one that you don't want to change unless its dependencies (e.g. parameters) change to reduce the number of re-rendering. For this one, make sure to check out the interactive example in the docs.

⚠️ Please note, don't use memoization for every function. This is a great article on the topic that explains the pros and cons, the whens and wheres.