Optimizing your application to increase performance should be the goal of every developer. Like me, I know a lot of internet users would rather shut down their computers than deal with a slow website that takes too much time to load its contents. The performance of an application is one of the things that endear users of it.
In today's tutorial, we will be discussing how to use React Hook to achieve a performance-driven application.
In React, when we talk about performance-oriented applications, we talk about useMemo. These hooks help us to memoize values or functions so we don't get to repeat these operations thereby causing a re-rendering in our application. Now let's dive into each of these hooks.
useMemo
This is the React hook that helps us improve the performance of our application. When the performance of an application improves, the speed improves alongside. useMemo memoizes an application's operation. In this context, when an operation is performed, useMemo stores the output or value of that operation, caches it and returns the output whenever the same operation is performed again. Instead of having to repeat the operation, useMemo just returns the output stored in the previous operation provided any of the values used in computing that operation does not change. This way, you don't have to repeat the operation over and over, thereby increasing the performance and speed of that application.
As a storekeeper whose tradition is to take stock of goods after the close of work for the day. If at the end of the next business day, no good was sold or restocked, will you have to take another count or just use the previous day's numbers? Your guess is as good as mine; use the previous day's numbers. That's the same thing useMemo does for us. Instead of having to perform the operation all over, it presents the previously stored output.
How to use useMemo
useMemo takes in two (2) arguments: the function calculating the value that will be stored and the dependencies.
import React, {useMemo} from 'react'
const memoValue = useMemo(memoFunction, dependencies)
The memoFunction here is the function that will perform the operation whose output will be cached. It has to be a pure function with no arguments. When the component first renders, the memoFunction's output will return. On subsequent renders, if the dependencies do not change, the initial output will keep returning, but once the dependencies change, React will call memoFunction, store the output so it can be used later and then return the output.
The dependencies on the other hand are the variables, state or props used in the memoFunction. These dependencies are the values that make up the output of the memoFunction.
Example without useMemo
import React, {useState} from 'react'
const UsememoTutorial = () => {
const [input, setInput] = useState(0)
const [counter, setCounter] = useState(0)
const memoFunction = (input) => {
console.log("we are running a square root");
return input * input
}
const memoValue = memoFunction(input)
const count = (e) => {
setCounter(counter + 1)
}
return (
<div>
<input type='number' value={input}
onChange={(e) => setInput(e.target.value)} />
<h3> Square root of your input is: {memoValue}</h3>
<hr />
<div>
<h3>Counter count is: { counter}</h3>
<button onClick={count}>Counter</button>
</div>
</div>
)
}
export default UsememoTutorial
We have 2 states in our component. Also, in our function (memoFunction), we have a message that gets logged to the console whenever any of the states change. You can try the code and you'll see for yourself. Next, we will see what the reactions look like when we memoize our function.
Example using useMemo
import React, {useMemo, useState} from 'react'
const UsememoTutorial = () => {
const [input, setInput] = useState(0)
const [counter, setCounter] = useState(0)
const memoFunction = (input) => {
console.log("we are running a square root");
return input * input
}
const memoValue = useMemo(() => memoFunction(input), [input])
const count = (e) => {
setCounter(counter + 1)
}
return (
<div>
<input type='number' value={input}
onChange={(e) => setInput(e.target.value)} />
<h3> Square root of your input is: {memoValue}</h3>
<hr />
<div>
<h3>Counter count is: { counter}</h3>
<button onClick={count}>Counter</button>
</div>
</div>
)
}
export default UsememoTutorial
Now, there is a bit of a difference in the code. We memoized the function (memoFunction) and used our input state as a dependency. The message in our console only gets logged when the input changes, and not when you click the button to increment the counter.
I am sure you are thinking, this looks exactly like useEffect, but well maybe yes, but not entirely. I'll explain a better scenario where you'll see a whole lot of difference between useMemo and useEffect.
When to Use useMemo
When you calculate the value of a variable or function, useMemo helps store up the output so you don't have to recalculate this same operation all over again when you have to. When you need this same value, it presents it to you.
If you've read other articles on this topic, I'm sure you'd have come across, a lot of places where it was made mentioned as the hook for expensiveCalculations. What that means is useMemo is used to optimize the performance of your application when you are working on a large project. If the project is small, don't use it because you'd probably not see so much of an effect, but the effect, speed and performance are glare when on a large application.
Imagine working on a social app that consumes resources at scale and where the application renders per second because of its large number of users. Leaving your application bare to re-render every second might lead to a performance problem that could crash the app. Memoizing the function responsible for this could be a great deal for the app to increase its performance level.
Summary
useMemo helps you increase the performance and speed of your application. And it is most effective when it's being used on a large application; there the effect on your application is obvious compared to using it on just a few lines of code. It helps to eliminate having to repeat yourself by doing the same calculation over and over. It just presents you the output of the last render when all the values remain unchanged.
Thanks for reading through even though I know it was a long read. Hope it was helpful and educative.
Do have a great day.