DEV Community

loading...

Understanding useMemo in react

Elizabeth
I am a frontend developer, and I write react.js code these days. I am hoping to share my knowledge with others. she/her
・4 min read

In my last post, we talked on useContext hook and we looked at some of the use cases for useContext. In this post we'll be talking about useMemo, why it is important, and when to use it. Let's jump right in.

What is the useMemo hook

The useMemo hook is a hook that kinda has a memory. It memoizes the value returned by a function. So to understand this useMemo better we'll take a look at a JavaScript technique called memoization.

What is Memoization

To be simply put, memoization is a technique that is used to increase the performance of a program by storing the result of a complex function call into a cache and returning the cached value when you give the same input to that function call. For example, say I have an add function that accepts 2 parameters and does a lot of complex execution before returning the addition of the 2 values, if I memoize that add function here's what happens.
When I call the add function the first time and pass in 2 and 3, it does all the complex execution and returns 5, then stores that into a cache. When next I call that same add function and pass the same values 2 and 3. Instead of doing all that complex execution, the program remembers that I passed 2 and 3 before, then it just returns the same value which is 5.

I have seen that one gif

The advantage of this is that the program wouldn't take all the time to run that function since it has been called before with the same input.

Back to useMemo

The useMemo hook accepts a callback function and a dependency, like useEffects, and returns a memoized value. It will only cause a component to re-render when the value of any of the dependency passed changes.

const complexFunction = useMemo(() => {
  ...
},[aValue]);
Enter fullscreen mode Exit fullscreen mode

When to use

You should only use this hook when running a function is really expensive. Your function should be running well at first, then you can think of adding the hook after.

Let's look at an example of how useMemo works
I personally don't use this hook a lot but to see an example, let's (intentionally) use a loop just slow down our runtime a little.
PS: do not try this at home! lol

import React, {useState} from 'react';

const thisFunctionWillSlowDownOurApp = (num1, num2) => {
/* this might cause an infinite loop. if you're using codesandbox */
const thisFunctionWillSlowDownOurApp = (num1, num2) => {
  for (let i = 0; i <= 10001; i++) {}
  console.log('That took a while');
  return +num1 + +num2;
 }

export default function App() {
  const [numToAdd, setNumToAdd] = useState(0);
  const [num2, set2] = useState(0);

  const addedValue = thisFunctionWillSlowDownOurApp(numToAdd);

  return (
    <div className="App">
      <input type="number" 
        value={numToAdd} 
        onChange={(e) => setNumToAdd(e.target.value)} />

      <input type="number" 
        value={num2} 
        onChange={(e) => set2(e.target.value)} />

      <div>{addedValue}</div>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

We can already see a problem in this code (Note that this example is just for demonstration purposes). And we can already see a performance issue in our program. And this is where useMemo comes in.

To make this code better we'll use the useMemo.

// import useMemo
import React, {useState, useMemo} from 'react';

const thisFunctionWillSlowDownOurApp = (num1, num2) => {
/* this might cause an infinite loop. if you're using codesandbox */
const thisFunctionWillSlowDownOurApp = (num1, num2) => {
  for (let i = 0; i <= 10001; i++) {}
  console.log('That took a while');
  return +num1 + +num2;
// the + before num1 and num2 will convert it to an integer
 }

export default function App() {
  const [numToAdd, setNumToAdd] = useState(0);
  const [num2, set2] = useState(0);

// Usage
  const addedValue = useMemo(() => {
    return thisFunctionWillSlowDownOurApp(numToAdd, num2);
  }, [numToAdd, num2]);


  return (
    <div className="App">
      <input type="number" 
        value={numToAdd} 
        onChange={(e) => setNumToAdd(e.target.value)} />

      <input type="number" 
        value={num2} 
        onChange={(e) => set2(e.target.value)} />

      <div>{addedValue}</div>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

This way when the same value is passed twice, the loop wouldn't run twice.

Why you shouldn't overuse the hook

The hook makes use of some complex logic so overusing it might be doing more harm than good to your component. Also, it is stated in the react documentation that the React might sometimes choose to β€œforget” some previously memoized values and recalculate them on the next render so your function should work well even without the useMemo.

Conclusion

The useCase for useMemo differs, depending on what you're working on you "might" not encounter a problem where you need to use it. But when you do, it could really help with performance. But I'd advise you don't use it when you're sure it's not necessary.

And that's the basic usage for useMemo. I hope this article has been able to help you understand this hook. In my next article, we'll be looking at the useRef hook.

Do you have other tips or questions? Please feel free to add it in the comment section and I will be happy to answer. Keep being amazing and stay safe out there. ✌🏾

Discussion (1)

Collapse
eichgi profile image
Hiram

I always wondered what is the purpose of useMemo. Thanks for the explanation 🀟