DEV Community

Cover image for useMemo y useCallback: cuándo sí sirven… y cuándo solo estorban
Leonardo Trujillo
Leonardo Trujillo

Posted on

useMemo y useCallback: cuándo sí sirven… y cuándo solo estorban

Hubo una etapa de mi vida como desarrollador donde pensaba que optimizar React significaba una cosa:
agregar useMemoy useCallback a todo lo que se moviera.

Si veía un cálculo, un array filtrado, una función…
“Memoízalo, por si acaso. No vaya a ser que React sufra.”

Y sí, React sufría… pero por culpa mía.

Este post es sobre cómo dejé de usar memoization como si fuera una aspirina para todo, y aprendí a aplicarla solo donde realmente aporta algo.
Si alguna vez te ha pasado que agregas useMemo y tu app va más lenta, créeme, estás en el lugar correcto.


🧩 La sobre-optimización que me estrelló contra la realidad

En uno de mis primeros proyectos grandes, tenía una lista enorme que se re-renderizaba seguido. Yo, muy confiado, pensé:

"¿Cuál es la mejor forma de optimizar React?
Fácil: memorizo todo 🥸☝🏼"

Y lo hice.
Cada función: useCallback.
Cada array: useMemo.
Cada cálculo: useMemootra vez.
Y practicamente así con todo ^_____^

Pero algo raro pasó:
la interfaz no iba más rápida… iba peor.

Se sentía "pesada", como si React estuviera peleando contra sí mismo.

Después recibí un feedback que me dejo pensando mucho:

"Leo… no puedes optimizar algo que no sabes si necesita optimización."

Y ahí me cayó el veinte.


⚙️ La revelación: memoization NO hace tu código más rápido

Yo pensaba que useMemo y useCallbackeran como un "modo turbo".
Pero la realidad es más simple y más dura:

useMemo evita un cálculo costoso
→ Solo si ese cálculo es realmente costoso.

useCallback evita que una función cambie de referencia
→ Solo si esa función se pasa a un componente memoizado.

Antes de eso, yo memorizaba filtros que tardaban 1 ms.
O funciones que ni siquiera pasaba como prop.

Era como ponerle cinturón de seguridad a una bicicleta estacionada.


🔍 useMemo en la vida real (no en el tutorial)

El propósito real:

const sortedList = useMemo(() => {
  return heavySortFunction(list);
}, [list]);
Enter fullscreen mode Exit fullscreen mode

Si heavySortFunction tarda 100 ms, esta línea te salva la vida.
Si tarda 0.5 ms, estás haciendo más trabajo del necesario.

💭 El momento en el que lo entendí

Un día estaba perfilando una app y me di cuenta de algo ridículo:
mi useMemo estaba tardando MÁS en comparar dependencias que el cálculo real que intentaba optimizar.

Ahí fue cuando dije: "Ok React, te escucho. Ya entendí."


🔧 useCallback: el primo que todos usan mal

Antes:
useCallback(() => console.log("hola"), [])
en todos lados.

Ahora sé que esta regla es real:

Si tu hijo no está memoizado, tu useCallback no sirve.

Ejemplo real en producción:

const handleClick = useCallback(() => {
  doSomething();
}, []);
Enter fullscreen mode Exit fullscreen mode

Si luego haces:

<Child onClick={handleClick} />
Enter fullscreen mode Exit fullscreen mode

🚦 Cuándo SÍ usar memoization (sin culpa)

Sin drama, sin misterio:

✔️ 1. Cuando un cálculo es verdaderamente pesado

Filtro gigante, sort complejo, cálculos matemáticos, parseo.

✔️ 2. Cuando pasas funciones a un componente memoizado

Ese es el matrimonio perfecto:
React.memo + useCallback.

✔️ 3. Cuando tienes listas enormes o renders costosos

Si tienes 300 items en pantalla → ahí sí vale la pena.


🛑 Cuándo NO usar memoization (cerrando ciclos tóxicos)

Esto me cambió la vida:

❌ Cuando es “por si acaso”

La sobre-optimización es el cardio del sufrimiento.

❌ Cuando lo que optimizas es rápido

No hay nada que ahorrar.

❌ Cuando el hijo no está memoizado

useCallback ahí es placebo.

❌ Cuando el componente es pequeño

Un memo innecesario solo añade complejidad.


📌 Mi checklist personal (para evitar recaer)

Antes de usar useMemo o useCallback, pregúntate:

¿Esto realmente es costoso?

¿Estoy evitando recrear algo que sí afecta a un hijo memoizado?

¿Tengo forma de medirlo?

¿Si lo quito, pasa algo?

¿Estoy optimizando para un caso real o para sentirme "más pro"?

Si la respuesta honesta es NO…
ciérralo.
No memorices.


🏁 Lección aprendida

Después de entender esto, dejé de pelearme con memoization y empecé a verla como lo que es:
una herramienta quirúrgica, no una cinta adhesiva para todo.

Hoy optimizo menos, pero optimizo mejor.
Y React me lo agradece.

En el próximo post voy a hablar del Profiler de React y cómo medir renders de verdad, sin adivinar.

Nos leemos 👋

Top comments (0)