Using useMemo instead of React.memo syntax issue

React.memo and React.useMemo are not equivalent at all (don't rely on naming similarity). Here's a quote from React.memo doc:

React.memo is a higher order component.

So it's a HOC that can optimize rendition of your component given that it renders the same output with the same properties.

React.useMemo on the other hand is more generic and returns a memoized value:

Pass a “create” function and an array of dependencies. useMemo will only recompute the memoized value when one of the dependencies (either a or b) has changed.

const memoizedValue = useMemo(
  () => computeExpensiveValue(a, b), 
  [a, b]
);

And while it can be hacked to be used instead of React.memo, it's not its purpose and it will add to the confusion more than it will help. useMemo is a hook and is subject to the certain usage rules.

And there's this warning as well:

In the future, React may choose to “forget” some previously memoized values and recalculate them on next render, e.g. to free memory for offscreen components. Write your code so that it still works without useMemo — and then add it to optimize performance.


While memo is a HOC and useMemo is a hook, you can use them the achieve the same result.

For context, HOC is an older React pattern that has been used for many years with class-based and functional components alike. You can still use it today (there's no plan for deprecation).

Hooks is a relatively new concept (about a year) that enhances functional components and in many cases drastically simplifies code. That's why many developers are moving towards using hooks.

Anyway, both memo and useMemo take two arguments: a function and props. If none of the props change on subsequent re-renders, the function is not executed again and instead returns the previous result. This, in effect, replaces shouldComponentUpdate callbacks, with a purely functional approach.

With memo, your code would look like this:

const SpeakerCardDetail = React.memo(
  (props) => <div>{props.name}</div>
)

With useMemo, you'd write:

const SpeakerCardDetail = (props) => useMemo(() => <div>{props.name}</div>)

Notice that useMemo is used inside of your component function, while memo wraps the function.

More traditionally, useMemo could be written as:

function SpeakerCardDetail(props) {
  return useMemo(
    () => <div>{props.name}</div>
  )
}

Now, the code above would re-render every time, making the useMemo function a bit useless. To make it work its magic, we need to add the second argument. (memo still works even without specifying the second argument but you can add it to customize it)

There's a slight difference in the format of the second argument. memo expects a function that compares previous and current props, just like shouldComponentUpdate does for class components.

const SpeakerCardDetail = React.memo(
  (props) => <div>{props.name}</div>
,
  // return true if passing nextProps to render would return the same result as passing prevProps to render, otherwise return false
  (prevProps, nextProps) => prevProps.name === nextProps.name
)

useMemo, on the other hand, expects an array as the second argument. Whenever the values in the array change, the function would be executed again.

function SpeakerCardDetail(props) {
  return useMemo(
    () => <div>{props.name}</div>
  ,
    [props.name]
  )
}

There's really no more magic than that. Both memo and useMemo are used to memoize the result of a function, the only difference is memo is a HOC (and can be used to wrap both class and functional components) which useMemo is a hook (and can only be used inside functional components).