useCallback Hook in react

Learn via video courses
Topics Covered

Overview

The useCallback is a react hook that lets us memoize a function block between the subsequent rendering of a component to improve the performance of the application. It simply means we can cache a function's definition, and we can avoid general re-computing of it again and again on every render; instead, we can instruct the react to only reconstruct it when we necessarily need, it by passing a set of dependency values in the form of an array.

What is the useCallback Hook in React?

useCallback is a React hook that lets us cache a function definition between re-renders. What does this mean?

This means we can improve the performance of our react app by preventing it from re-building specific pieces of code again, and why would we want that?

Often in our react application, we would have a variety of components for various functionalities. Now let's imagine the whole application first; suppose if, for every small change made in the app, our entire application re-renders itself; how much costly it would be when considering the performance? Yes, it might get unnoticed for small projects, but on a big scale, it could cost a considerable amount of resources and time. So that's not what we would want.

Now, let's think of just one component. Suppose there is a component in our application that is handling two-three similar functionalities. Now, if on change of any of the concerned parameters, the whole components re-build itself every time, then similarly as we discussed for the complete application above, having this would also be less cost-efficient in terms of resource usage. So what should we do now?

The answer is we can cache a variable value, an object, or a function (I will be discussing what caching means in a moment) so that it only gets rebuilt or re-rendered when we want it to be. Now, what does caching mean? Caching, in simple words, means we have calculated a value, and we are not recalculating it again unless not necessary.

Now, let's have a look at the technicality. The `useCallbackuse callbacks a memorized callback function, memoized as we discussed above, which means caching a value to prevent its recalculation unless not necessary. Doing so allows us to isolate resource-intensive functions, so they do not automatically get rendered on every render.

The useCallback hook accepts a list of dependency arrays, which consists of a set of parameters, and in this way, we instruct the useCallback hook to only re-run and compute the function if any of the elements from the dependency array changes. And as a result, we can avoid its re-rendering up to a certain level, which can boost the application's performance.

Alright, enough theory; let's understand this with the help of an example.

Syntax of useCallback

The useCallback hook in React accepts two parameters.

  • functionToCache - It is the function definition we want to cache, so that its automatic re-rendering can be avoided.
  • dependencyArray - It is an array with a list of dependencies, which means values. It is an array of those values, which, if changed, then we want the function to render itself again and re-compute the result.

Usage of useCallback

Why is there a need for useCallback?

Let's see an example to understand it.

In the above example, we have created a function multiplyNumbers(), which returns another function by taking two inputs and returning their product. Now, why did we do that? Because using this, we can see one thing, even if the variables result1 and result2 are assigned the same function, there is no input at that point, just simply the function. Still, when we console logged their equality, they returned false, meaning both of them, in the very initial state too, are referencing different instances of the same multiplyNumbers() function, and that's the way JavaScript works.

Now, why we talked about this? When a component gets re-rendered, then every function inside it gets recreated, and as a result, the references of those functions get changed between those renders.

The use callback (functionToCache, dependencyArray) hook will return a memoized or cached instance of the function we want to cache, which will only get re-computed if any value inside the dependencyArray gets changed. By doing this, we have made it possible to retain the function object between different renders.

Creating React Application

We can initialize a react app by simply typing

into the terminal, it only requires nodejs to be installed on the system beforehand.

Let's now create a simple react application, and we will see both cases; in the first, we will not use the useCallback hook, and in the latter one, we will be using it.

Without useCallback

App.js file

Tasks.jsx file

Output before pressing the Increment button

Output before pressing the Increment button

Output after pressing the Increment button

Output after pressing the Increment button

We can see here even the component Tasks.jsx has nothing to do with the incrementing of the count state, but still, it is getting re-rendered every time we press the Increment button. Imagine this happening on an extensive scale application, this will waste a considerable amount of resources. So how to prevent it? Using the useCallback hook.

With useCallback

We can use the useCallback hook to instruct the react to only re-render that component if anything specific to it gets changed. For example - the Add Task functionality. We would want to react to only recreate the Tasks function inside the Tasks. jsx component if any state or values specific to it gets to change. Now, let's see how we can do that.

App.js file

Tasks.jsx file

Output before pressing the Increment button

Output before pressing the Increment button 2

Output after pressing the Increment button

Output after pressing the Increment button 2

Output after pressing the Add Task button

Output after pressing the Add Task button

Explanation

Here, we can see that we have cached the result of our addTask() function using the useCallback hook and have instructed react to only re-compute and reconstruct the function if the state associated with it, i.e., the tasks state gets changed. And we can see that in that output, after clicking on the Increment button, the child component, i.e., the Tasks component, was not getting rendered, but as soon as we clicked on Add Task button, the component got recomputed and we can see the result in the console.

useCallback Vs useMemo

The one-liner difference between both would be, the useCallback returns a memoized function while the useMemo returns a memoized value.

useCallback is used for optimizing the rendering behavior of the components in a react application, while useMemo is used to memoize resource-expensive functions to avoid having to call them on every render. Syntax-wise, both the useCallback and the useMemo expect a function and a dependency array to be passed to them. The difference is the useCallback hook returns the function when any of the dependencies gets changed, while useMemo calls the function and returns the result.

Fuel Your Full-Stack Passion! Enroll in Our Full Stack Certification Course Taught by Industry Experts and Get Certified!

FAQs

Q: Why useCallback is used?

A: Often when the complexity of the application increases, there are chances of its performance going down. There could be many possible reasons for that, one of which is the unnecessary rendering of child components inside a parent component even though it's not needed. Hence by using the useCallback hook, we can avoid that and can help in improving the application's overall performance.

Q: Should useCallback be used everywhere ?

A: No, using the useCallback hook is not recommended everywhere in the program. The reason for this is that, as we have seen in the above example, usage of the useCallback hook somewhere adds complexity to the code readability. It indeed provides excellent functionality to the application, but we should use it sparingly. And should only use it where it's necessary.

Q: When useCallback should not be used?

A: Like everything, useCallback also has its drawbacks, the primary one being the added complexity in the code. Also, there are certain use cases where the cost of making the optimization costs more than not having the optimization (generally for smaller projects); again, it depends according to the situation. But the point to remember here is unless not needed, it should not be used.

Conclusion

  • The useCallback is a react hook that lets us cache a function's definition.
  • And by doing so, we can avoid recreation of that function again and again on every render unless not necessary.
  • Syntax - useCallback(functionToCache, dependencyArry);
  • The useCallback accepts two parameters, the first being the function that we want to cache.
  • And the second is the dependency array, which will consist of a list of values, and once any of those will change, then the useCallback hook will reconstruct the passed function.
  • The useCallback and the useMemo hooks are almost similar; the only difference is the useCallback hook returns the function when any of the dependency array items gets changed.
  • Whereas the useMemo hook calls the function and returns the newly computed result.