How to use useCallback() hook

Improve your React components performance by using useCallback().

ReactOne
3 min readNov 21, 2021

Improving performance In React applications includes preventing unnecessary renders and reducing the time a render takes to propagate. useCallback() can help us prevent some unnecessary renders and therefore gain a performance boost.

In this post, we’ll take a close look at the useCallback() hook and how to properly use it to write better React code.

1. Functions equality

Before diving into useCallback(), let’s have a quick refresher about the concept of referential equality and function equality.

In JavaScript, functions can be treated just like any other variable. a function can be passed as an argument to other functions, returned by another function, assigned as a value to a variable, compared, and so on. In short, it can do anything that an object can do.

Functions are treated like any other variable and thus are First-class functions.

Let’s implement a function called sumFunctionFactory(), which returns another function that sums numbers. Then let’s use that function to create two functions function1 and function2.

Function inequality (function1 !== function2)

The functions function1 and function2 share the same code source, but they are distinct separate function objects, meaning they refer to different instances, thus Comparing them evaluates to false and that’s just how JavaScript works.

2. The useCallback() hook

Going back to React, when a component re-renders, every function inside of the component is recreated and therefore these functions’ references change between renders.

useCallback(callback, dependencies) will return a memoized instance of the callback that only changes if one of the dependencies has changed. This means that instead of recreating the function object on every re-render, we can use the same function object between renders.

const memoized = useCallback(() => {   // the callback function to be memoized },  // dependencies array[]);

3. Use case scenario

Passing callbacks to optimized child components

useCallback is especially useful to prevent unnecessary renders when passing callbacks to optimized child components that rely on reference equality. Imagine you have a component that renders a list of items:

Child component <MyList>

To prevent unnecessary expensive list re-renderings, you wrap it into React.memo().

The parent component<ParentComponent> provides a handler function to the child component <MyList>:

ParentComponent <ParentComponent>

handler callback is memoized by useCallback(). As long as dep is the same, useCallback() returns the same function object. When <ParentComponent> re-renders, the handler function object remains the same and doesn’t break the memorization of <MyList>.

avoiding unnecessary renders of child component using React.Memo() and React.useCallback()
The console log

4. When you should not use useCallback()

Let’s make sure we don’t go overboard. useCallback() has its downsides, primarily code complexity. There are a lot of situations where adding useCallback() doesn’t make sense and you just have to accept function recreation.

useCallback() has its performance drawbacks, as it still has to run on every component re-render.
In this example, useCallback() is not helping optimization, since we’re creating the clickHandler function on every render anyways; actually, the optimization costs more than not having the optimization.

Inline functions are generally cheap, the re-creation of functions on each rendering doesn’t cause performance issues.

Poor usage of React.useCallback()

5. Conclusion

useCallback(callback, dependencies) can be used like useMemo(), but it memoizes functions instead of values, to prevent recreation upon every render. allowing you to avoid unnecessary re-rendering which makes your application more efficient.

When thinking about performance upgrades, always measure (or profile) your component speed before the optimization process. Optimization increases complexity, and as a developer, you should always make sure that the tradeoff is worthwhile.

For more cool content and projects just like this one please Follow us and consider checking our Github Repository :

--

--

ReactOne

We are a small team of React Native and AWS experts