When using functional components in React we may run into situations where we are performing expensive calculations multiple times, even though the values passed in to the functional component hasn't changed.
This is where useMemo
hook comes in. In this lesson we are going to learn how to use useMemo
hook to optimize an expensive (in this example - highly expensive operation of adding two numbers together, for simplicity) operation so that its result is recalculated only when it's necessary - that is, when the input arguments have changed. Otherwise, we are going to use an optimized, memoized result.
Instructor: [00:00] We start with a very simple React component, which has a count, the state over here. By default, the counter is set to 0and also, we have a button which allows us to increment the counter when we click it. We can see that this works just fine.
[00:12] Also, there's this expensive component, over here. Let's see what it does. We are simulating an expensive operation, in this case, it's going to be basically adding two numbers together, but imagine if it was like a database call or something much more expensive than adding.
[00:27] Let's take a look inside of dev tools, how many times does console.log.expensive is going to be actually printed. Let me refresh that. You will note that when I click the button, this word, this expensive message, is going to keep popping up.
[00:40] It's because this addNumber function is actually going to change the state of this entire component. As such, this expensive component is going to be rendered again. We would like to be able to optimize that, so this expensive operation is triggered only once, and triggered again whenever either the first or second argument actually change.
[01:01] Luckily, there's a new hook that's going to help us. To use it, import useMemo from React. To use this hook, do const optimized = useMemo. This hook takes two arguments. The first one is the function that we want to optimize. In our case, it's going to be the expensive operation. We are going to pass in those first and second arguments.
[01:22] The second argument is an array of arguments that we want the useMemo to watch for. In essence, whenever the first or second argument is going to change, we would like to run the useMemo function again. Otherwise, just keep on using this optimized value. We're going to pass into our component, like this.
[01:40] Let's take another look in the dev tools. I'm going to refresh the page, and you will notice that this word, this expensive message, is going to pop up because the component has just been mounted, but if I increment the counter, you will see that I no longer get those messages, because useMemo allows us to keep the result of this expensive operation optimized, so we can use it over here.
[02:00] UseMemo can optimize our expensive operation because we are always passing the same arguments. Let's see what happens if I pass this stateCounter to this component. Now, whenever I click the button, the value of this expensive operation is going to be calculated every single time. Because the first argument we passed into this functional component is the counter, which changes every single time I click the button.
[02:26] We might decide that we don't want to care about this first value and would like to only run this expensive operation again, only if the second argument is going to change.
[02:36] If we save it and refresh, we can see that even though I'm incrementing the counter, this word, this expensive message pops only once, because this expansive operation is not running again, due to the fact that the second argument hasn't changed.