Aprende cuándo React.memo, useMemo y useCallback aceleran de verdad tu app, y cuándo la complican para nada.
Abrir esta lección en KodokonCuando un componente se vuelve a renderizar, todos sus hijos se vuelven a renderizar por defecto, hayan cambiado sus props o no. No es una tragedia: un render solo toca el DOM si la salida cambia. La memoización se vuelve relevante cuando renders frecuentes se encuentran con subárboles costosos. Tres herramientas, tres objetivos: React.memo omite el render de un componente si sus props son superficialmente iguales, useMemo cachea un valor calculado, useCallback cachea una función. Las tres se basan en la igualdad de referencia.
import { memo } from "react";
const Row = memo(function Row({ item, onSelect }) {
return (
<li onClick={() => onSelect(item.id)}>{item.label}</li>
);
});La cadena es tan fuerte como su eslabón más débil. Si una sola prop recibe una referencia nueva en cada render - una función flecha en línea, un objeto o array literal - la comparación de memo falla y el componente se vuelve a renderizar de todos modos. useCallback estabiliza la referencia de la función para que la comparación tenga éxito.
import { useCallback } from "react";
function List({ items }) {
const handleSelect = useCallback((id) => {
console.log("selected:", id);
}, []);
return (
<ul>
{items.map((item) => (
<Row
key={item.id}
item={item}
onSelect={handleSelect}
/>
))}
</ul>
);
}useMemo tiene dos usos legítimos: evitar un cálculo genuinamente costoso (ordenar o agregar miles de elementos), y estabilizar una referencia consumida por un hijo memoizado o listada en las dependencias de un efecto. Para un cálculo trivial, la caché cuesta más de lo que ahorra: comparación de dependencias, memoria retenida, lectura más pesada.
import { useMemo } from "react";
function Stats({ orders }) {
const total = useMemo(() => {
return orders.reduce(
(sum, order) => sum + order.amount,
0
);
}, [orders]);
return <p>Total: {total} €</p>;
}