Pankaj Singh

Self-taught Web Developer

Better React Performance – When to Use the useCallback vs useMemo Hook

In this article you will learn the differences between useCallback and useMemo as well as how to measure the gain of the improvements you're getting in the codebase. Before we begin, you should note that the following methods for optimising React are really last resort options. Before you apply these utilities, your own code will offer you more opportunities for improvement than most of the performance gain you'll get by using what you will learn here. Still, it's important to know these tools and know when to use them if you see the opportunity. Resources You'll Need to Follow Along Official Beta Documentation for useCallback and useMemo Example Project Source Code Example Project Live Demo As always, I've provided a sample project so that you can test in a simplified environment everything that is explained here. No big deal, the example project is just a summary of the main points you will learn now. Before we start comparing these two hooks, let's review some necessary background concepts.

>

What is Referential Equality?

When React compares the values used in a dependency array such as useEffect, useCallback, or props passed to a child component, it uses Object.is(). You can find the detailed explanation of Object.is here but in short: Primitive values are equal (check the link above for the few exceptions). Non-primitive values refer to the same object in memory.

In a simplified example:


"string" === "string" // true 0 === 0 // true true === true // true {} === {} // false [] === [] // false const f = () => 'Hi' const f1 = f const f2 = f f1 === f1 // true f1 === f2 // false

How React.memo Works

Now I'll briefly explain how React.memo works (but we'll also discuss it later in the article). When appropriate, you can use it to improve performance. When you want to avoid unnecessary re-renders on a child component (even if the parent component changes), you can wrap the whole component with React.memo – as long as the props do not change. Also, note referential equality here – the child component will not be re-rendered.

import { memo } from 'react'; const ChildComponent = (props) => { // ... }

export default memo(ChildComponent) Now that you know how React.memo works, let's start. How the useCallback Hook Works useCallback is one of the built-in hooks we can use to optimise our code. But as you'll see it's not really a hook for direct performance reasons. In short, useCallback will allow you to save the function definition between component renders.

import { useCallback } from "react" const params = useCallback(() => { // ... return breed }, [breed])

The usage is pretty straightforward:

Import useCallback from React because it is a built-in hook. Wrap a function for which you want to save the definition. As in useEffect, pass in an array of dependencies that will tell React when this stored value (the function definition in this case) needs to be refreshed. One of the first things to note is precisely the function definition part. It stores the definition, not the execution itself, not the result – so the function will be executed every time it is called. Because of this, don't use this hook to avoid lengthy calculations.

So what is the advantage of storing a function definition?

Back to Referential Equality If the function itself is used, not the returned value, such as: Dependency on useEffect or any other hook. Prop of a child component, context, and so on. To achieve true equality between renders, useCallback will store the function definition with the same reference to the object in memory. Without this hook, in each render the function will be recreated and point to a different in-memory reference. So React will understand that it is different even if you use React.memo in your child component. You can test this behaviour in the example project. You'll see that, with the non-optimised version, every time you write the side effect of a child component is triggered.

Article By Pankaj Singh

Skilled in programming language JavaScript, comfortable with the latest versions ES6. Also having good Python knowledge with strong OOPs concept. Full Stack Developer using NodsJs/Django for Backend with CSS/HTML/JavaScript/MDBootstrap, API, MySQL,MongoDB,Github and Herokuapp. Analytical thinker that consistently resolves ongoing issues or defects, often called upon to consult on problem that have eluded resolution from others.

Discuss about post

Subscribe to my weekly newsletter

Read Also

How to make your company website based on bootstrap framework...