Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Bionic Julia
Bionic Julia

Posted on • Originally published atbionicjulia.com on

     

React.memo and useMemo - What's the Difference?

Since first learning React and then building production-ready apps with it, I've been somewhat confused about when it's appropriate to use the memoization wrappers and hooks. The main ones are:

  • React.memo
  • useMemo
  • useCallback

Speaking to other engineers about this, I've gotten responses all the way from "just use it wherever possible - there's no downside", to "not sure...but it's a good idea to use it when rendering lists". None of these answers were satisfactory, so I set aside some time to figure this out once and for all.

Things I'll cover in the series (which I'll break up into separate blog posts for digestibility):

  • React.memo vs.useMemo - What's the difference?
  • When to use andnot useReact.memo.
  • When to use andnot useuseMemo.

React.memo vs. useMemo - What's the difference?

React.memo

React.memo is a higher order component that's used to wrap a React functional component. The way it works is:

  • React does an initial render of the component when it first loads and stores it in memory.
  • React does ashallow comparison of prop values. Iftrue, React uses the memoized component and skips a re-render. Iffalse, React re-renders the component.

A contrived example looks like this:

exporttypeVideoGameProps={rating:string,name:string,releaseDate:string,}// NOTE React.memo wraps the entire componentexportconstVideoGame:React.FC<VideoGameProps>=React.memo(({rating,name,releaseDate})=>(<div><p>Name:{name}</p><p>Rating:{rating}</p><p>Release date:{releaseDate}</p><hr/></div>))
Enter fullscreen modeExit fullscreen mode

Tip 1: You can pass a second argument in to define a stricter comparison function, instead of using the default shallow comparison.

constcheckStrictEquality=(prevProps,newProps)=>{// blah blah}React.memo(Component,checkStrictEquality)
Enter fullscreen modeExit fullscreen mode

Tip 2: Because of the use of shallow comparison, be careful about passing in non-primitive props like an object, array or function. Do not pass these in directly as props, but instead, instantiate and assign these to variables which are then passed in. For functions, theuseCallback hook is handy for ensuring the same instance of the function is passed in as props, thus allowing the shallow prop comparison to result intrue. For objects and arrays, theuseMemo hook might be helpful, which I'll go through in the next section.

constonClickHandler=useCallback(()=>{// blah blah},[insertdependencieshere]);exportconstVideoGame:React.FC<VideoGameProps>=React.memo(({rating,name,releaseDate,onClickHandler})=>(<div><p>Name:{name}</p><p>Rating:{rating}</p><p>Release date:{releaseDate}</p><buttononClick={onClickHandler}>Click</button><hr/></div>));
Enter fullscreen modeExit fullscreen mode

Tip 3: If you're working with class-based components, think about using aPureComponent instead.PureComponents allow you to defineshouldComponentUpdate() which does a shallow comparison of props and state.

useMemo

useMemo is aReact hook that can be used to wrap a function or object, within a React component. Similarly toReact.memo, the idea is that the function will be run once and the value memoized. This hook takes 2 arguments, the computational function, and an array of dependencies that the function depends on. React will only recompute the memoized value if the value of one of the dependencies changes.

A contrived example:

exporttypeVideoGameSearchProps={allGames:VideoGameProps[],}exportconstVideoGameSearch:React.FC<VideoGameSearchProps>=({allGames})=>{const[searchTerm,setSearchTerm]=React.useState('')const[count,setCount]=React.useState<number>1// NOTE useMemo here!!constresults=useMemo(()=>{console.log('Filtering games')returnallGames.filter((game)=>game.name.includes(searchTerm))},[searchTerm,allGames])constonChangeHandler=(event:React.ChangeEvent<HTMLInputElement>)=>{setSearchTerm(event.target.value)}constonClickHandler=()=>{setCount((prevCount)=>prevCount+1)}return(<><inputtype="text"value={searchTerm}onChange={onChangeHandler}/>{results.map((game)=>(<VideoGamekey={game.name}rating={game.rating}name={game.name}releaseDate={game.releaseDate}/>))}<br/><br/><p>Count:{count}</p><buttononClick={onClickHandler}>Increment count</button></>)}
Enter fullscreen modeExit fullscreen mode

There's quite a lot going on in the example above, but if you just focus on theconst results function, the computed value is memoized and stored, and only recalculated if either thesearchTerm orallGames array changes. If we hadnot used theuseMemo hook, theresults function would have been constantly recalculated every time we clicked on thebutton to increment thecount state, even though this does not directly affect theresults. This is because a state change causes theVideoGameSearch parent component to rerender, thus forcing a recalculation ofresults.

Concluding notes

The reason I say these are contrived examples are because... they are. I made these examples up for the purposes of illustration, and without more context, it's difficult to say whether the use ofReact.memo oruseMemo would be worth it here. The reason for this is that React is already super speedy in how it performs its re-renders. If you're going to intercept this process, and introduce complexity, you should be sure that the tradeoff is indeed worth it.

In the next blog post, I'll go into more detail on when it might make sense to use theReact.memo wrapper.

Comments, thoughts, edits? I'm onTwitter andInstagram@bionicjulia.

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Formerly a banker and tech startup founder. Now on my 3rd career as a full stack software engineer (with a front end focus). Posts on tech and things learnt on my programming journey. 👩🏻‍💻
  • Location
    London
  • Work
    Software Engineer
  • Joined

More fromBionic Julia

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp