A Guide To Using React’s useMemo Hook
In this guide, you will learn what the
useMemo hook means, how you can use it to optimize your React applications, and when you should use it. You will also get to know other options you can use in other situations, so you don’t use the
useMemo hook when you should not.
useMemo hook memoizes values in your React application. These values usually come from expensive functions, and you use the
useMemo hook to store the value, so the expensive function doesn’t always run.
💡 Expensive functions are those that require a significant amount of time and resources (memory or processing power) to execute.
What is memoization?
Memorization is a powerful optimization technique that caches computation results to retrieve them from the cache when needed. Hence, this speeds up your code because you don’t need to repeat unnecessary computations of expensive functions.
An excellent example is the Fibonacci sequence. Each number in the Fibonacci sequence, or “Fibonacci number,” is the sum of the two numbers in the sequence before it. This sequence starts with 0 and 1. The third number is the addition of the first two in the sequence, which are 0 and 1, to become 1, and so on, as seen below:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...
If you are to write a program to solve this, you can use recursion because each element is the sum of the previous two elements:
The above uses recursion; meaning it will continue to call a copy of itself until its value is less than one, then it returns one. To understand this better, here is an illustration of how this will work if you want to calculate for
In the above, you will notice that
fibonacci(0) are calculated several times, which can affect the speed when you have to do more expensive calculations or if you want to get the 35th value.
You can fix this by introducing memorization, which lets you store the values of these positions and only return them instead of having to recompute them several times:
The code above checks if there is a cached value; if so, it prevents recursion. If there is no cached value, it calculates the recursion and saves it to the cache immediately before returning the value. To understand this better, here is what the illustration for
fibonacci(5) now looks like:
💡 Cache is a type of temporary storage that a computer or program uses to hold data that is likely to be accessed again in the near future.
There is no repetition, and the functions with blue backgrounds are getting “memoized values” instead of recomputing them.
Now that we have a basic understanding of memoization, let’s see how it can help you store the values of expensive computations in your React application for better performance.
React re-rendering problem
In React, whenever a state or prop updates or value changes, the component(s) re-renders, meaning all expensive functions, computations, and API requests are re-rendered, leading to slow performance. It doesn’t matter if the state has nothing to do with the other components; when a state changes in the parent component, every other component will re-render.
To explain this, let’s create a react application that involves expensive calculations like the factorial calculation:
In the application above, there are two states, one to store the number from the input form while the second to store the name. Basically, what this application does is that any number you input into the number field will calculate the factorial using the external function placed outside the component:
This expensive function is called inside the component, and the number state is passed into it, so it calculates the value, and you can then display it in the application:
But the problem here is that whenever a state is updated, this function will always run even when the state does not affect the number state. For example, there is a
name state; whenever you type into the name input field, it will always re-render the component, thereby always running this expensive function.
Let’s test this. If you pass a number from
35 upwards, you will begin to notice that it takes some seconds to calculate. This is because it will need to do a lot of recursions, as you can see in the GIF below.
That is not the problem, but the problem is that when you try to do anything on your application that involves a state, it will take time because the application will re-render. Meaning the Fibonacci function will always calculate the value for the number passed.
As you see below, when I type the name, even though it shows the component re-renders, it takes time for the name to appear because the function is calculated for each render.
To fix this, you will introduce the
useMemo hook to store the value of expensive calculations and operations and stop them from continually rendering even when the component re-renders.
useMemo is an official hook you can import from
At this point, when you update other states or props in your component, as long as the
number state does not change, the value will be stored. The expensive function will not compute, making the performance of your application fast:
Understanding the useMemo hook
useMemo hook is one of the many built-in react hooks that allow you to memoize values in React applications. It is used basically in two situations which are:
- When computing expensive operations
- For referential equality
Overall, it memoizes computed values in a React component so that those values will not be recomputed when the component re-renders. This is the general syntax of the
useMemo hook receives two arguments and is very similar to the `useEffect` hook. The first argument is a callback function, which returns the value, and the second is an array of dependencies. When any of the values of any dependencies changes, a re-computation happens, and then the value is memoized again, which triggers the expensive operation. Just as you have seen in the previous example:
Arrays and objects will always return false even though they are equal because their equality is based on references, meaning:
When objects or functions are declared within your component, they will always be redeclared whenever your component re-renders. Let’s confirm this in this example.
Suppose you have an object that contains styles; you want to use these styles to control the dark mode and light mode display of your application:
darkTheme state is created and has a default value of
false. When the button is clicked, the value changes to
true, and then the color will change based on the
themeStyles object. But the issue is that whenever the component re-renders, this object is redeclared. Let’s track this by introducing a
useEffect hook and passing
themeStyles as its dependency so it logs out a message whenever the
themeStyles is redeclared:
Whenever the name state changes, you will notice the object is redeclared:
You can fix this with the
useMemo hook by memoizing the
themeStyles object so it only redeclares when the
darkTheme state changes:
With this, the
useEffect hook will only run when the
darkTheme state changes.
useMemo best practices
You now know what the
useMemo hook does and how it helps optimize your React application. This doesn’t mean you should memoize all values in your React application; instead, you should only memoize values forexpensive functions and referential equality.
The primary goal is to avoid recomputing expensive functions and operations during re-render and resolve reference conflicts between renders It is essential to know that this hook caches these values; thereby, unnecessary memoizing values will lead to using up more memory which can hurt your application.
In React, you can use other hooks and methods to memoize other aspects of your code to ensure optimization. You can use the
useCallback hook to memoize expensive functions. For example, the
calculateFibonacci function that was placed outside the component, you can decide to place it within the component but wrap it with the
You can also use React Memo to memoize the rendered output of a component by wrapping around it, thereby avoiding unnecessary renderings.
Run the sandbox to view the memoized function in action:
In this guide, you have learned what the
useMemo hook is about, how it works, and when you should use it—knowing when and where you should apply memorization and the specific method to use is essential.
Thanks for reading!
Hi, I’m Elijah, a technical writer, and software developer, actively sharing all I’ve learned through writing. Follow me on Twitter if you enjoy programming tips and memes.