React memo, useMemo y useCallback (con refs, portales y useId)

React memo, useMemo, useCallback, forwardRef, portales y useId

React memo vs useMemo vs useCallback, forwardRef, portales, useId | We.Inc

Cuándo usar memo, useMemo y useCallback en React, con contadores de renderizado en vivo. Además, forwardRef y ref como prop en React 19, modales con createPortal, etiquetas con useId y una lista virtual de 10,000 filas.

Envuelve un componente en memo para saltarte renderizados cuando sus props no cambian. Usa useCallback para mantener igual una prop de función entre renderizados, y useMemo para cachear un objeto o un cálculo lento. Solo importan junto con memo o cuando hay un coste real. Mide primero con el React Profiler; los contadores en vivo de abajo muestran la diferencia.

Una línea para cada uno

Las demos cuentan renderizados reales en tu navegador. Escribe en cada caja con el interruptor apagado y encendido, y observa los contadores. La segunda mitad cubre las APIs de referencia que aparecen junto al trabajo de rendimiento: refs, portales e ids.

Preguntas frecuentes

¿Qué diferencia hay entre useMemo y useCallback?

useMemo invoca tu función y cachea el valor que devuelve. useCallback cachea la propia función. useCallback(fn, deps) equivale a useMemo(() => fn, deps).

¿Debo envolver todos los componentes en memo?

No. Comparar props también cuesta tiempo, y la mayoría de los renderizados son baratos. Usa memo donde el Profiler muestre un componente que se renderiza a menudo con las mismas props y tarda un tiempo apreciable.

¿Está obsoleto forwardRef?

En React 19, los componentes de función aceptan ref como una prop normal, así que el código nuevo no necesita forwardRef. Sigue funcionando, y el equipo de React ha dicho que quedará obsoleto en una versión futura.

¿Por qué usar un portal para un modal?

Un modal dentro de una tarjeta con overflow hidden o un transform puede quedar recortado o apilado debajo de otro contenido. Renderizarlo en document.body con createPortal evita ambas cosas y lo mantiene en tu árbol de React.

¿Puedo usar useId para las keys de una lista?

No. useId sirve para atributos de accesibilidad como htmlFor y aria-describedby. Las keys deben venir de tus datos, por ejemplo un id de base de datos.

Cómo medir

Errores habituales

Tabla de decisión: memo, useMemo, useCallback u otra cosa

Qué herramienta para qué problema

Contadores de renderizado, antes y después

memo: saltarse renderizados cuando las props son iguales

Escribe en la caja. Sin memo, la lista se vuelve a renderizar con cada tecla aunque sus props no cambiaron. Con memo se renderiza una vez.

useCallback: mantener la misma función

Pasar una función flecha en línea rompe memo, porque se crea una función nueva en cada renderizado. useCallback devuelve la misma hasta que cambian sus dependencias.

useMemo: cachear un cálculo lento

Filtrar 20,000 productos en cada renderizado es trabajo desperdiciado cuando solo cambió un valor no relacionado. useMemo vuelve a ejecutar el filtro solo cuando cambian los productos o la búsqueda.

forwardRef, ref como prop, portales y useId

forwardRef (React 18 y anteriores)

Un padre no puede pasar ref a un componente de función a menos que el componente la reenvíe. forwardRef pasa la ref hasta un elemento real.

ref como prop (React 19)

Desde React 19, los componentes de función reciben ref como cualquier otra prop, así que forwardRef ya no hace falta en código nuevo.

createPortal para modales y tooltips

Un portal renderiza los hijos en otro nodo del DOM, normalmente document.body, para que un modal escape de padres con overflow hidden o un z-index bajo. Los eventos de React siguen propagándose por el árbol de React.

useId para parejas de etiqueta y campo

useId da un id único que coincide entre el renderizado del servidor y el del navegador, así que varias copias del mismo componente de campo nunca chocan.

Listas largas

react-window: una lista de 10,000 filas

List renderiza solo las filas visibles y unas pocas más. Cada fila recibe index y style; style posiciona la fila y debe aplicarse. La demo de al lado usa la misma idea, escrita a mano.

¿Creas formularios? useId combina bien con

React Hook Form

Lista renderizada {n} veces ({count} elementos)

Envolver la lista en memo

Escribe aquí

({n} renderizados)

Usar useCallback

Pequeño

Mediano

Grande

Elegido: {x}

Cachear con useMemo

Filtrar productos

Clic no relacionado ({n})

{matches} de 20,000 coinciden. El filtro se ejecutó {runs} veces; la última tardó {ms} ms.

Buscar

Enfocar la búsqueda

Esta caja tiene overflow hidden y, aun así, el modal cubre toda la ventana.

Abrir modal

Demo de portal

Me renderizaron en document.body con createPortal.

Cerrar

Email

Respondemos en un día.

Email (otra vez)

Mismo componente, id distinto.

10,000 clientes

Cliente {n}

10,000 filas, pero ahora mismo solo hay {n} en el DOM.

Empieza gratis · Sin tarjeta de crédito

Relacionado: Guías

Producto

Para quién es

Funciones

Recursos

Empresa

Mapa del sitio