Ir al contenido principal

useMemo de React

 ¿Para qué sirve useMemo?

¡Qué buena pregunta! Al igual que useCallback, el hook useMemo es una herramienta de optimización en React, pero se aplica a valores (cálculos) en lugar de funciones.


¿Qué es useMemo?

useMemo es un hook que te permite memoizar (almacenar en caché) el resultado de un cálculo costoso y devolver ese resultado almacenado en caché en renderizados posteriores, siempre y cuando sus dependencias no hayan cambiado.

Piensa en él como una forma de decirle a React: "Oye, no vuelvas a calcular este valor a menos que cambien estas variables específicas."

Sintaxis

JavaScript
const valorMemoizado = useMemo(() => {
  // 1. La función que realiza el cálculo costoso
  return calcularValorLento(a, b);
}, [a, b]); // 2. Array de dependencias
  1. Función de Fábrica: Es la función que realiza el trabajo de cálculo. Solo se ejecuta si las dependencias cambian.

  2. Array de Dependencias: Una lista de variables que, si cambian, obligan a React a ejecutar la función de fábrica y recalcular el valor.


¿Para qué se usa? (Los dos usos principales)

useMemo se utiliza principalmente para dos propósitos clave de optimización:

1. Evitar Cálculos Costosos

Este es el uso más directo. Si tienes una función que tarda mucho tiempo en ejecutarse (por ejemplo, iterar sobre un array enorme, calcular la ruta más corta, o realizar análisis complejos), y el componente se re-renderiza con frecuencia por cambios menores (como mover el mouse o actualizar un input secundario), no quieres que ese cálculo se ejecute cada vez.

Caso de Uso: Filtrar, ordenar o agrupar una lista muy grande de datos.

JavaScript
function ComponenteLista({ items, filtro }) {
  // Sin useMemo, esta función se ejecuta en CADA render,
  // incluso si solo cambia un contador del padre.

  const listaFiltrada = useMemo(() => {
    console.log("¡Cálculo costoso de la lista ejecutado!");
    return items.filter(item => item.name.includes(filtro));
  }, [items, filtro]); // 👈 Solo se recalcula si 'items' o 'filtro' cambian.

  // ... usar listaFiltrada en el render
}

Al usar useMemo, la función filter solo se ejecuta si items o filtro tienen una referencia diferente. Si solo cambia una variable de estado no relacionada, se devuelve el resultado de la última ejecución, ahorrando tiempo de procesamiento.

2. Evitar Re-renderizados de Componentes Hijos (Estabilidad de Referencia)

Este uso es similar a useCallback, pero aplica a objetos y arrays.

Cuando React re-renderiza un componente:

JavaScript
// En cada render, React crea un *nuevo* objeto literal en memoria
const estiloNuevo = { color: 'red', fontSize: '16px' };

// Si pasamos este objeto a un componente hijo optimizado con React.memo:
<ComponenteOptimizado estilo={estiloNuevo} />
// El hijo se re-renderiza porque, aunque los valores internos son los mismos,
// la referencia de memoria de 'estiloNuevo' es diferente en CADA render.

Para evitar que este componente hijo optimizado se re-renderice, necesitas garantizar que la referencia del objeto (estiloNuevo en este caso) sea estable.

useMemo garantiza la estabilidad de la referencia:

JavaScript
function ComponentePadre({ valor }) {
  // 🌟 useMemo garantiza que 'estiloMemoizado' será el mismo objeto
  // en CADA render si 'valor' no ha cambiado.
  const estiloMemoizado = useMemo(() => ({
    color: valor > 10 ? 'red' : 'blue',
    fontSize: '16px'
  }), [valor]); // 👈 Solo se recrea el objeto si 'valor' cambia.

  // El hijo solo se re-renderiza si 'valor' cambió o si alguna otra prop obligatoria cambió.
  return <ComponenteOptimizado estilo={estiloMemoizado} />;
}

Resumen de la Tríada de Optimización

HookObjetivo¿Qué Memoiza?¿Cuándo Usarlo?
useMemoOptimizar cálculos costosos.Un valor (objeto, array, número, string) o el resultado de una función.1. Tienes un cálculo lento. 2. Necesitas una referencia estable (para React.memo).
useCallbackOptimizar funciones pasadas como props.Una función.Cuando pasas un callback a un componente hijo optimizado con React.memo.
useEffectSincronizar con sistemas externos.El ciclo de vida y la ejecución de efectos secundarios.Llamadas API, suscripciones, manipulación de DOM.

En resumen, useMemo es tu herramienta para el caching de valores que consumen recursos, asegurando que tu aplicación se mantenga rápida al evitar cálculos repetitivos.

Comentarios

Entradas populares de este blog

Crear proyecto de frontend con Vite, React, Tailwind, Typescript y JSX

 ¿Cómo se crea un proyecto exclusivo de frontend con Vite, React, Tailwind, Typescript y JSX? ¡Absolutamente! Entiendo que quieres la guía completa para pasar de cero a tener un proyecto de frontend moderno, vacío y listo para ser llenado con tu código. A continuación, te proporciono un archivo de guía detallada que incluye todos los comandos necesarios para inicializar el proyecto, configurar Tailwind CSS, y los pasos clave para empezar a "poblarlo". Voy a generar un documento Markdown con la guía paso a paso, incluyendo los comandos de terminal y las modificaciones esenciales a los archivos de configuración. Guía: Creación de un Proyecto Frontend Puro (Vite, React, TypeScript, Tailwind) Este documento detalla el proceso para inicializar un proyecto de frontend vacío y optimizado, utilizando Vite como empaquetador, React como librería, TypeScript para tipado y Tailwind CSS para estilizado. 1. Inicialización del Proyecto con Vite Vite es la herramienta más rápida para emp...

Tokens V2

Tokens: Programme to discover tokens, where there are not. Now available at  https://puszcza.gnu.org.ua/projects/tokens/ This is Version 2, for  version 1, go here . Synopsis: use TokensV2; sub printFile; my @FORMAT = ( ['<Message Date=".*?" Time=".*?" DateTime=".*?" SessionID=".*?"><From>(?:<User FriendlyName=".*?"/>)+</From><To>(?:<User FriendlyName=".*?"/>)+</To><Text(?: Style=".*?")?>.*?</Text></Message>',   sub {     my $fh = $_[1];     my ($d, $t, $f, $s, $T) = $_[0] =~ m|<Message Date="(.*?)" Time="(.*?)" DateTime=".*?" SessionID=".*?">(<From>(?:<User FriendlyName=".*?"/>)+</From>)<To>(?:<User FriendlyName=".*?"/>)+</To><Text(?: Style="(.*?)")?>(.*?)</Text></Message>|;     my $F = join '<br />', ...

Perl Net::LDAP::SimpleServer

Adaptaciones sobre el módulo LDAP Server para Windows (Strawberry Perl) Lista de adaptaciones (continúa más abajo): - Relajación de condiciones de bind:     - Cuenta principal (principal account)     - Validación de contraseñas Ubicación del archivo: %Strawberry_Perl%\site\lib\net\ldap\SimpleServer\ProtocolHandler.pm CPAN: http://search.cpan.org/~russoz/Net-LDAP-SimpleServer-0.0.17/lib/Net/LDAP/SimpleServer.pm Código: package Net::LDAP::SimpleServer::ProtocolHandler; use strict; use warnings; # ABSTRACT: LDAP protocol handler used with Net::LDAP::SimpleServer our $VERSION = '0.0.17';    # VERSION use Net::LDAP::Server; use base 'Net::LDAP::Server'; use fields qw(store root_dn root_pw allow_anon); use Carp; use Net::LDAP::LDIF; use Net::LDAP::Util qw{canonical_dn}; use Net::LDAP::FilterMatch; use Net::LDAP::Constant (     qw/LDAP_SUCCESS LDAP_AUTH_UNKNOWN LDAP_INVALID_CREDENTIALS/,   ...