Hook useMemo
Cachea el resultado de un cálculo costoso entre renderizados.
Busca en todas las páginas de la documentación
Cachea el resultado de un cálculo costoso entre renderizados.
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥
Tarjeta de referencia rápida - lista para copiar y pegar.
const memoizedValue = useMemo(() => computeExpensive(a, b), [a, b]);
// Memoiza un array/objeto derivado para estabilizar referencias
const filtered = useMemo(
() => items.filter((item) => item.active),
[items]
);Cuándo usarlo: Tienes un cálculo costoso que no debe volver a ejecutarse en cada renderizado, o necesitas una referencia estable de objeto/array para un array de dependencias o prop de hijo.
"use client";
import { useMemo, useState } from "react";
function fibonacci(n: number): number {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
export function FibonacciCalculator() {
const [num, setNum] = useState(10);
const [theme, setTheme] = useState<"light" | "dark">("light");
const result = useMemo(() => fibonacci(num), [num]);
return (
<div className={theme === "dark" ? "bg-gray-900 text-white p-4" : "bg-white text-black p-4"}>
<label className="flex items-center gap-2">
n =
<input
type="number"
value={num}
onChange={(e) => setNum(Number(e.target.value))}
className="w-20 border rounded px-2 py-1"
max={40}
/>
</label>
<p className="mt-2 font-mono">fibonacci({num}) = {result}</p>
<button
onClick={() => setTheme((t) => (t === "light" ? "dark" : "light"))}
className="mt-2 px-3 py-1 border rounded text-sm"
>
Cambiar tema
</button>
</div>
);
}Lo que esto demuestra:
fibonacci es memoizado y solo se recalcula cuando num cambiauseMemo, cada re-renderizado (incluyendo cambio de tema) volvería a ejecutar el cálculo costosoObject.isuseMemo es una optimización de rendimiento, no una garantía semántica - React puede descartar el caché en algunos casos (p. ej., componentes fuera de pantalla)| Parámetro | Tipo | Descripción |
|---|---|---|
factory | () => T | Función que calcula el valor a memoizar |
dependencies | unknown[] | Array de valores reactivos de los que depende el cálculo |
| Retorno | Tipo | Descripción |
|---|---|---|
memoizedValue | T | Resultado en caché de la función factory |
Estabiliza un objeto para un array de dependencias:
const options = useMemo(
() => ({ page, pageSize, sortBy }),
[page, pageSize, sortBy]
);
useEffect(() => {
fetchData(options);
}, [options]);Memoiza una lista filtrada/ordenada:
const sortedUsers = useMemo(
() => [...users].sort((a, b) => a.name.localeCompare(b.name)),
[users]
);Memoiza un árbol de componentes (raro):
const chart = useMemo(
() => <ExpensiveChart data={data} />,
[data]
);// El tipo de retorno se infiere de la factory
const total = useMemo(() => items.reduce((sum, i) => sum + i.price, 0), [items]);
// total: number
// Genérico explícito cuando la inferencia es muy amplia
const config = useMemo<Config>(() => ({ retries: 3, timeout: 5000 }), []);Optimización prematura - Envolver cada valor en useMemo añade complejidad sin beneficio medible para cálculos baratos. Solución: Perfila primero. Solo memoiza cuando puedas medir un problema de rendimiento.
Dependencias faltantes - Omitir una dependencia causa que el valor memoizado sea obsoleto. Solución: Incluye todos los valores reactivos usados dentro de la factory.
Referencias de dependencias inestables - Si una dependencia es un objeto/array nuevo en cada renderizado, useMemo recalcula de todas formas. Solución: Memoiza la dependencia misma, o reestructura para depender de primitivos.
Efectos secundarios en la factory - useMemo se ejecuta durante el renderizado; los efectos secundarios (fetching, subscripciones) rompen las reglas de React. Solución: Mueve los efectos secundarios a useEffect o manejadores de eventos.
No es una garantía - React puede descartar valores memoizados para componentes fuera de pantalla y recalcular más tarde. Solución: Nunca confíes en useMemo para la corrección - solo para el rendimiento.
| Alternativa | Úsalo cuando | No lo uses cuando |
|---|---|---|
| Sin memoización | El cálculo es barato (concatenación de strings, matemática simple) | El cálculo es notablemente lento |
React.memo | Quieres omitir el re-renderizado de un componente hijo completo | Necesitas memoizar un valor, no un componente |
useCallback | Necesitas una referencia de función estable, no un valor estable | Necesitas cachear un valor no función |
useDeferredValue | Quieres diferir el renderizado de contenido costoso sin bloquear entrada | Necesitas cachear resultados de cálculo |
| Cálculo del lado del servidor | El trabajo costoso puede ocurrir en tiempo de construcción o solicitud | Los datos dependen del estado del lado del cliente |
¿Cuándo vale la pena? Como regla general, memoiza cuando el cálculo toma más de ~1ms o cuando el resultado se usa como dependencia para useEffect, useCallback, o se pasa a un hijo React.memo.
useMemo cuando el cálculo toma más de ~1ms (perfila primero).useEffect, useCallback, o se pasa a un hijo React.memo.useMemo.useMemo es una optimización de rendimiento, no una garantía semántica.Object.is, así que una referencia nueva significa "cambió".useMemo(() => value, deps) cachea el valor de retorno de la función factory.useCallback(fn, deps) cachea la función misma (equivalente a useMemo(() => fn, deps)).useMemo para valores, useCallback para funciones.useMemo se ejecuta durante el renderizado, así que los efectos secundarios (fetching, subscripciones, mutaciones del DOM) rompen las reglas de React.useEffect o manejadores de eventos.const options = useMemo(
() => ({ page, pageSize, sortBy }),
[page, pageSize, sortBy]
);
useEffect(() => {
fetchData(options);
}, [options]); // referencia estable, el efecto solo se vuelve a ejecutar cuando los valores cambianinterface Config {
retries: number;
timeout: number;
}
const config = useMemo<Config>(
() => ({ retries: 3, timeout: 5000 }),
[]
);
// config: ConfiguseMemo tiene sobrecarga - almacenar el valor, comparar dependencias y mantener el caché.const chart = useMemo(
() => <ExpensiveChart data={data} />,
[data]
);data no ha cambiado.React.memo en el componente mismo para la mayoría de casos.useMemo es para cálculo del lado del cliente que depende del estado del cliente.useMemo(() => items.reduce((sum, i) => sum + i.price, 0), [items]) infiere number.useMemo para funcionesuseMemo para evitar re-ejecutar efectosRevisado por Chris St. John·Última actualización: 16 jul 2026
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥