Entendiendo el gancho useMemo en React [Guía Completa]

El hook useMemo se utiliza para memoizar valores en aplicaciones React. useMemo memoiza valores calculados en un componente React para que en caso de que el componente se vuelva a renderizar, esos valores no se vuelvan a calcular. Este artículo te enseñará qué es el hook useMemo y cómo usarlo.

Añada afiliaciones a su proyecto Webflow en cuestión de minutos.

Empezar

Más de 200 componentes Webflow clonables gratuitos. No es necesario registrarse.

Ver biblioteca

Añade membresías a tu proyecto React en cuestión de minutos.

Empezar

What is a useMemo hook and what is it used for?

React has so many in-built hooks that allow you to do different lifecycle stuff in functional components, and there’s the useMemo hook. Why would you need this hook?

This hook is used for memoizing values in React applications. Memoization is an optimization technique that involves storing computed values in memory to avoid recomputation. This process speeds up program execution as computations would only have to execute once until specified to recompute.

Bringing this understanding to React, the useMemo hook memoizes computed values in a React component such that in cases of a component re-render, those values will not be recomputed.

The syntax of this hook is:


...
const value = useMemo(() => {
  return somevalue
}, [...dependencies])
...


It receives two arguments: a callback function that returns a value assigned to the variable and a dependencies array. The dependencies array informs the useMemo hook of when it needs to recompute a value, i.e., when one of the dependencies’ value changes, a recomputation happens, but until then, no recomputation.

Use cases of the useMemo hook

Avoiding Expensive Recomputation during Rerender

When a state is updated, the component is rerendered, and every value that may have been computed when the component mounted will be recomputed with the new state. For simple calculated values, this may not be a big deal. But for expensive calculations (like slow functions or functions that are doing so many things in them), optimization would be recommended.

Some computed values in React components depend on the state being updated, so when the state changes, we expect a recomputation of that value to get updated data. However, some computed values may depend on a different state, and this means such values should not be recomputed all the time.

And this is where useMemo comes in. Let’s look at an example without useMemo:


function App() {
  const [number, setNumber] = useState(0)
  const [darkTheme, setDarkTheme] = useState(false)

  const someValue = () => {
    // a slow function that uses the number state to compute and return a value
  }

  const toggleTheme = () => {
    setDarkTheme(t => !t)
  }

  const updateNumber = () => {
    setNumber(number + 1)
  }

  return (
    
) }


In this component, we have two states: number and darkTheme. And we have a variable, someValue which we’ll assume is a slow computation. And we have two functions for updating the state.

With this, when you execute the toggleTheme function, the component rerenders and someValue is recomputed again. And this happens when you also execute the updateNumber function. For our case, we only want someValue to be recomputed when the number state changes, as this value has no relationship with the theme, and as slow as it is, we want to improve the experience of our application.

With useMemo imported, we can do this:


...
  const someValue = useMemo(() => {
    // a slow function that uses the number state to compute and return a value
  }, [number])
...


This way, someValue will only be recomputed when the number (the dependency of the useMemo) changes. If it doesn’t, the memoized value will be used. Using this, we’ve improved the experience of our application.


For resolving reference conflicts between renders

When a component rerenders, existing objects and functions in the component will be redeclared, and just as you may already know with objects, two objects with the same content are different as they both point to different references in memory. Here’s what I mean:


const obj1 = { name: 'JavaScript' }
const obj2 = { name: 'JavaScript' }

obj1 !== obj2


Reference conflicts can happen in React components just like this example:


function App() {
  const [number, setNumber] = useState(0)
  const [darkTheme, setDarkTheme] = useState(false)

  const someValue = () => {
    // a slow function that uses the number state to compute and return a value
  }

  const toggleTheme = () => {
    setDarkTheme(t => !t)
  }

  const updateNumber = () => {
    setNumber(number + 1)
  }

  const themeClasses = {
    primaryColor: darkTheme ? '#333' : 'white'
  }

  useEffect(() => {
    console.log('themeClasses changed')
  }, [themeClasses])

  return (
    
) }


I introduced a themeClasses object with the primaryColor property that is different for light and dark theme. I also added a useEffect hook that simply logs “themeClasses changed” when the themeClasses object (the dependency) changes.

What we would expect from this is that, when the theme changes, the primaryColor property changes, thereby changing the themeClasses object and the log, “themeClasses changed”. But we get is different. If you try this on your browser, you’ll get “themeClasses changed” when you change the theme state, and also when you change the number state. Here’s why.

The themeClasses object is redeclared when the state changes. And as I explained earlier, the themeClasses object in the first render IS NOT EQUAL to the themeClasses object in the second render. To the useEffect hook, the object has changed, so the callback is run again.

This is where the useMemo hook comes in again. We can memoize the themeClasses object and only redeclare it when the darkTheme state changes, here’s how:


...
  const themeClasses = useMemo(() => {
    return {
        primaryColor: darkTheme ? '#333' : 'white'
    }
  }, [darkTheme])
...


With this in place, the useEffect hook will only run when the darkTheme state changes.


Do not use useMemo all the time

We’ve seen how relevant the useMemo hook is but, don’t use it every time. “This value doesn’t depend on this state…hmm..useMemo it is”…no!!!!

As helpful as useMemo is, you also need to understand that this hook is using some part of your memory to store these values. If you use useMemo everywhere in your application. this will use up more resources in memory and can negatively impact your application.

For computed values that are not slow or expensive, there’s no harm in recomputing them. For change in object references that do not affect your application, there’s no need memoizing them. Only use this hook where you actually need it to optimize your app.


Conclusión

In this article, we’ve seen how the useMemo hook works, it’s relevance and two use cases where you can optimize your application with the hook. We’ve also seen why you shouldn’t use this hook all the time / everywhere in your application.

You can also check out the useCallback hook which works similarly to this, but a bit differently.

ÍNDICE
Dillion Megida
¿Qué es Memberstack?

Autenticación y pagos para sitios Webflow

Añada inicios de sesión, suscripciones, contenido cerrado y mucho más a su sitio Webflow: fácil y totalmente personalizable.

Más información
Haga clic aquí para probar Memberstack en directo
Empezar a construir

Pruebe Memberstack y descubra todo lo que puede crear.

Memberstack es 100% gratis hasta que estés listo para lanzarla - así que, ¿a qué estás esperando? Crea tu primera aplicación y empieza a construir hoy mismo.