What is useMemo, and How It Works in React?
useMemo in React is essential react hook for improving the performance and speed of your application by caching the output in the computer memory and returning it when the same input is given again.
So how does this hook works in ReactJs? Let’s use a real-life example to explain this concept. Assuming that your high school teacher asked you for the total number of students in your class, you counted the students and told him that it was 50. You wouldn’t need to do the counting again when he asks you the next day. All you need is to give him the same answer as yesterday unless some new students were added to your class; now you have to count or calculate again. This is how the React memo hook works.
The React useMemo hook performs some calculations when requested and caches the result in the computer memory. Whenever the React memo hooks are asked to perform another operation with the same value, the old result will be returned without needing to waste computer resources calculating all over again.
The Syntax
The React hooks useMemo take two arguments in its parameter. These arguments are an array of dependencies and some functions whose output you want to cache. By default, the useMemo hook will execute the function you passed as an argument after the initial render.
How to Use the useMemo() React Hook
You can start using the useMemo hook in your next React project by following the steps below:
useMemo() Hook
Step 1: Import the hook from the React library:
import { useMemo } from "react";
Step 2: Compute with the useMemo hook:
const memodVal = useMemo(() => {/* function */}, [/* Dependencies */]);
Step 3: Render the useMemo result on screen:
<div className="App">{memodVal}</div>
useMemo() — an Example
import "./styles.css";
import { useState, useMemo } from "react";
export default function App() {
const [grade, setGrade] = useState(5);
const countPopulation = ((grade) => {
return grade ** 2;
});
const memoizedVal = useMemo(() => countPopulation(grade), []);
return (
<div className="App">
<p>Current Grade: {grade}</p>
<p>Current Population: {memoizedVal}</p>
</div>
);
}
useMemo() vs useCallback()
The useMemo hook and the react useCallback hook are very similar. Both use memoization caching techniques; however, the main difference between these two hooks is that, while the useCallback hook allows you to memoize the entire function, the useMemo hook only will enable you to memoize the output of functions.
Enroll in the best Web Development courses to strengthen your career in web development.
For instance, this is how closely related useMemo is to useCallback…
import "./styles.css";
import { useState, useMemo } from "react";
export default function App() {
const [grade, setGrade] = useState(3);
const countPopulation = (grade) => grade ** 2;
const memoizedVal = useMemo(() => countPopulation(grade), [grade]);
return (
<div className="App">
<RenderVal grade={grade} val={memoizedVal} />
</div>
);
}
const RenderVal = ({ grade, val }) => {
return (
<>
<p>Current Grade: {grade}</p>
<p>
Current Population: {' '}
{typeof val === 'function' ? val() : val}
</p>
</>
);
};
Now, let’s see how to use it along with the react useCallback hook…
import "./styles.css";
import { useState, useCallback } from "react";
export default function App() {
const [grade, setGrade] = useState(3);
const countPopulation = countPopulation(grade), [grade]);
const memoizedCallback = useCallback (() => countPopulation(grade), [grade]);
return (
<div className="App">
<RenderVal grade={grade} val={memoizedCallback} />
</div>
);
}
const RenderVal = ({ grade, val }) => {
return (
<>
<p>Current Grade: {grade}</p>
<p>
Current Population: {' '}
{typeof val === 'function' ? val() : val}
</p>
</>
);
};
Use Memoization with Care
While the useMemo hook can improve your app's performance, you should also run some scans on your codebase to determine which operations must be memoized. Only after the scan should you decide if memoization is worthwhile. When memoization is used inappropriately, it can lead to other performance issues.
Check out the App development course online by KnowledgeHut and get training in various fields of App development.
When to Run the useMemo() React Hook
There are three conditions where useMemo can be the best option for you, and they are discussed below:
Only After Initial Render
Going by this first option, the hook will run once and never again after the initial render. The function will not be executed again even if something causes the component to re-render. Instead, it will return the function's memoized output. This will be repeated for each subsequent re-render.
If this option is what you want to do, then the dependency array must be left empty. This means that the useMemo hook should not be watching any values. It should always return the previously memorized or cached output.
See the implementation below…
import "./styles.css";
import { useState, useMemo, useEffect } from "react";
export default function App() {
const [grade, setGrade] = useState(3);
const countPopulation = (grade) => {
return grade ** 2;
};
const memoizedVal = useMemo (
() => countPopulation(grade),
[/* Nothing to watch for */]
);
useEffect(() => {
console.log(`Initial Memoized Value is: ${memoizedVal}`);
}, [memoizedVal])
return (
<div className="App">
<RenderVal grade={grade} val={memoizedVal} />
<button
onClick={
() => setGrade(prevGrade => prevGrade += 1)
}>Increase Grade</button>
</div>
);
}
const RenderVal = ({ grade, val }) => {
return (
<>
<p>Current Grade: {grade}</p>
<p>Current Population: {val}</p>
</>
);
};
Only When Dependency Changes
When the specific value changes, the second option is to run useMemo and execute the function you passed. This will come in handy if the function you passed as an argument accepts a value from the outside world. If this outside value changes, you would want to recalculate the output to ensure it is correct.
You must specify the value you want to "watch" as one of the dependencies to accomplish this. useMemo will then monitor this value and execute the function you specified whenever the monitored value changes. If it does not change, useMemo will return the memoized value, which is the value from the most recent execution.
See the code block below…
import "./styles.css";
import { useState, useMemo, useEffect } from "react";
export default function App() {
const [grade, setGrade] = useState(3);
const countPopulation = (grade) => {
return grade ** 2;
};
const memoizedVal = useMemo(() => countPopulation(grade), [grade]);
useEffect(() => {
console.log(`Initial Memoized Value is: ${memoizedVal}`);
}, [memoizedVal]);
return (
<div className="App">
<RenderVal grade={grade} val={memoizedVal} />
<button onClick={() => setGrade((prevGrade) => (prevGrade += 1))}>
Increase Grade
</button>
</div>
);
}
const RenderVal = ({ grade, val }) => {
return (
<>
<p>Current Grade: {grade}</p>
<p>Current Population: {val}</p>
</>
);
};
How To Use React useMemo() Hook API Reference In React Native
From the image above, you can see that for every click of the increase grade button, the useMemo hook does some recalculation because it has a watch value.
After Every Re-render
The final option is to instruct useMemo to re-run the function you specified on each re-render. Doing this will nullify the sole purpose of using a useMemo hook. It is meaningless to use a useMemo to memoize something only to clear it out. Nevertheless, because this is an option, we must showcase it. A little warning to you, this option is a complete waste of time and is not recommended for use.
Let's say this is your only option, which is not true. You must remove the dependency array to persuade the useMemo hook to run on every render. The only argument required this time is the function.
Let’s see the code snippet below…
import "./styles.css";
import { useState, useMemo, useEffect } from "react";
export default function App() {
const [grade, setGrade] = useState(3);
const countPopulation = (grade) => {
return grade ** 2;
};
const memoizedVal = useMemo(() => countPopulation(grade));
useEffect(() => {
console.log(`Initial Memoized Value is: ${memoizedVal}`);
}, [memoizedVal]);
return (
<div className="App">
<RenderVal grade={grade} val={memoizedVal} />
<button onClick={() => setGrade((prevGrade) => (prevGrade += 1))}>
Increase Grade
</button>
</div>
);
}
const RenderVal = ({ grade, val }) => {
return (
<>
<p>Current Grade: {grade}</p>
<p>Current Population: {val}</p>
</>
);
};
How To Use React useMemo() Hook API Reference In React Native
From the example above, the useMemo kept re-computing on every re-render aborting the real purpose of using the useMemo hook since we removed the dependency array.
Use useMemo Hook with Caution
Optimization and performance are vital ingredients for developing a scalable and production-ready application. But by pursuing performance and optimization too much, you could end up introducing more problems than solutions in your code. You can easily overuse the React useMemo hook, that is why you must consider your options carefully before deciding to use the useMemo hook. Keep in mind that using the hook often adds some overhead, that is, the hook introduces new complex logic that must be considered.
It can also cause new performance issues that you didn't expect. When you memoize something, it is saved in your computer memory. This provides more room for the CPU to process data faster. However, resources are still being used, for instance, memory is used more for caching your data. The only difference is the type of resource it consumes.
Finally, do not create side-effects with functions passed to the useMemo hook. Side effects should be implemented within the useEffect hook. Additionally, do not use useMemo to update React state values. This is also a side effect, but it is worth mentioning. Use useMemo only for what was designed for memoizing and caching output values. To stay abreast of the latest react dev tools, visit top 12 react developer tools - extensions.
Conclusion
That's much important information to take in in one tutorial. I hope this tutorial has helped you better understand performance optimization in ReactJs.
The React useMemo hook can be helpful when looking for ways to improve the performance of your React applications. It can help you optimize costly computations by memorizing their output and re-running them only when necessary.
If you enjoyed this tutorial, consider learning from our ecosystem; check out the KnowledgeHut React Native training.
Top comments (0)