DEV Community

Cover image for React Performance Booster - Introduction to the useMemo hook

React Performance Booster - Introduction to the useMemo hook

Rasaf Ibrahim on October 26, 2023

Hooks have revolutionized the way developers build React applications, offering a more intuitive and functional approach to state and side effects....
Collapse
 
brense profile image
Rense Bakker

Anything you do in the render function should be memoized, otherwise you risk all kinds of weird behavior in your app, because you're going to cause rerenders that you may not have intended. Unintended rerenders usually have different state than you expect, often forcing you to write null checks to handle that unintended state. If you want to define something that doesnt depend on state, do it OUTSIDE of your component.

Collapse
 
thethirdrace profile image
TheThirdRace

Hard disagree. This is the mistake most devs actually make.

Do not overuse useMemo, only use it when necessary. This article actually nails it perfectly.

I rarely use useMemo and I never have performance problems in the apps I work on. More often than not, if your component re-renders too much, you have an architecture problem. Slapping useMemo would just be a band-aid on the problem, it wouldn't cure it.

Collapse
 
brense profile image
Rense Bakker

React.memo is a band-aid. useMemo is a necessity to ensure your state is consistent between renders. It ensures the state of your component only changes when you actually intend for it to change.

Thread Thread
 
thethirdrace profile image
TheThirdRace

useMemo has its uses, which the article does a very nice job to explain which ones.

What you suggested is everything you should NOT do with useMemo. There is no point to argue against this, useMemo is only there IF you have performance problems, which is extremely rare and more often a sign of a bad component architecture.

I don't know if you're a native English speaker or not, but the words you use have meanings in the context of React. Unfortunately, because the words you use, you seem to mix concepts together and perpetrate the wrong information as a side effect. Take for example your last comment:

useMemo is a necessity to ensure your state is consistent between renders. It ensures the state of your component only changes when you actually intend for it to change.

I'm sorry to have to point it out, but this is 110% wrong. useMemo has nothing to do with state. state is either coming from a useState, useReducer or an external store. useMemo doesn't come near these concepts at any point.

Some people are mixing the concept of state with props which is NOT the same thing at all, your words seem to point out you're making a similar mistake with useMemo.

The truth is, useMemo doesn't play any role with state. It doesn't ensure your state is consistent between renders and it doesn't ensure the state of your component only changes when you actually intend for it to change. Your state is always consistent and is managed by React. The useMemo command will not affect state and the callback function you pass to it should never modify state otherwise you will have an infinite loop.

The use of useMemo is to encapsulate an expansive function so that if the dependencies don't change, it will bypass the expansive function and return a cached value. That's it! Nothing less, nothing more.

Thread Thread
 
brense profile image
Rense Bakker

I'm sorry to say but you are 120% wrong about what application state is. Props are just a means of passing state down to child components. useMemo produces state just like useState or useReducer... I'm entirely lost as to why you would want to claim otherwise...

Thread Thread
 
thethirdrace profile image
TheThirdRace • Edited

It's the very first time you allude to application state.

As I said, the meaning of words is important and using the right words in the right context is important.

When we're talking about React, using the word state means the actual React state concept; what the lib actually tracks internally as state. For which everything I said is 100% correct.

When we're talking about application state in the greater sense of it, then yes what you said makes a lot more sense. I still feel you're bending way too much what application state technically means, but ultimately, I can understand where you're going with it.

It's important to be precise. You can't expect people to connect a very specific concept in React to a much broader sense of the word without giving the correct context 🤷‍♂️

Collapse
 
rajaerobinson profile image
Rajae Robinson

Very informative post. I definitely agree to avoid overusing useMemo. One way to figure out whether or not a process needs to be optimized is to use React's Profiler to check for performance bottlenecks.

Collapse
 
rasaf_ibrahim profile image
Rasaf Ibrahim

Thanks for sharing an informative article.

Collapse
 
Sloan, the sloth mascot
Comment deleted
Collapse
 
rasaf_ibrahim profile image
Rasaf Ibrahim

Thanks for your feedback! Glad you found the examples helpful.

Collapse
 
gunslingor profile image
gunslingor

Isn't useEffect basically the same thing since it's watching things for changes in the second arg?

Collapse
 
brense profile image
Rense Bakker

useMemo is executed as part of the render cycle and is resolved before rendering starts. useEffect is executed as part of the render cycle as well, but rendering will not wait for the result. useEffect is basically a backdoor to the world outside of the React scope. It allows you to handle side effects and produce a new state which wil cause a new rerender. useMemo will not cause a rerender.

Collapse
 
thethirdrace profile image
TheThirdRace

The truth is, "render cycle" could mean many things to different devs. It's too easy to not quite catch the difference between render and render cycle.

It would be more appropriate to describe both as below...

useEffect

useEffect is a callback function called asynchronously after the render.

It can be called before or after the browser painting phase, there's no guarantee when it will run beside it's gonna be after the render.

It should be used to synchronize data with external system, the function will even be called twice in a row in development to force you to make the callback function idempotent.

It doesn't return any value to the render, it's "disconnected" in the same manner a setTimeout would be.

useMemo

useMemo will be called during the render, it's a synchronous function just like useState.

It will directly return a value you can assign to a variable which the render will use immediately.

Thread Thread
 
brense profile image
Rense Bakker

Rendering is the act of updating the UI with the current state of the application. React apps do this in cycles. Each cycle follows a particular order of rules which are meant to ensure the correctness of the state of the app. In other words, you can only update state once between each render cycle. What useMemo does is return a state value based on other state properties in the current render cycle. The render cycle waits for useMemo to return a result before it continues with the next steps. useEffect, like useMemo (and other hooks) is executed during the render cycle, but you cannot change the state of the current render cycle inside the useEffect. Changes to the state inside useEffect will trigger another render cycle with a new state once the current cycle completes.

Thread Thread
 
thethirdrace profile image
TheThirdRace

To clear up any misunderstandings in what render is, I highly suggest these readings:

Both articles explains pretty well what is a render and what are the misconceptions perpetrated by the majority of React developers.

As for how you describe useMemo in your comment, you're close but you're also mixing concepts. See my follow up comment on useMemo to understand why I say you're mixing concepts and why useMemo has nothing to do with state

Thread Thread
 
brense profile image
Rense Bakker

I think you're confusing application state and literal state from the useState hook 🤷