Enero 2025. Nuevo año, mismo drama: un cliente quiere su dashboard en React. "Pero yo hago backend", le dije. "Y landing pages", agregué esperanzado. "Necesitamos React", insistió. Y aquí estamos, hermano, hablando de hooks avanzados como si supiera lo que estoy haciendo.
La verdad es que React y yo tenemos una relación complicada. Es como esa ex que juraste nunca volver a ver, pero aparece en cada proyecto. Y lo peor es que ahora, después de pelear tanto con hooks, casi... casi me está gustando.
Por qué terminé aprendiendo React (spoiler: dinero)
El proyecto era simple en papel: un dashboard para gestión de inventarios. "Lo hago en PHP con algo de JavaScript vanilla", pensé inocentemente. Pero no. El cliente había leído en Medium que React era el futuro y no había forma de convencerlo de lo contrario.
Tres Red Bulls después, ahí estaba yo, a las 2 AM, leyendo la documentación de React por enésima vez, tratando de entender por qué mi componente se renderizaba 47 veces por segundo. Liss me trajo café (bendita sea) y me preguntó si todo bien. "Sí, solo React siendo React", murmuré mientras veía mi laptop como si fuera a explotar.
*Se eliminaron las comillas simples para evitar problemas de compatibilidad
useState: El gateway drug de los hooks
Empecemos por lo básico. useState es como las variables de PHP, pero con esteroides y problemas de personalidad. Cada vez que cambias el estado, React dice "ah, interesante, voy a re-renderizar TODO".
// Lo que yo pensaba que hacía
const [contador, setContador] = useState(0);
setContador(contador + 1); // Simple, ¿no?
// La realidad: React re-renderiza el universo entero
// Tu componente, sus hijos, los hijos de sus hijos...
// Hasta el componente del vecino se entera
Al principio no le di importancia. "¿Qué tan malo puede ser?", pensé. Hasta que mi dashboard empezó a ir más lento que Windows Vista en una Pentium 4.
useCallback: Cuando las funciones tienen crisis de identidad
Aquí es donde la cosa se pone rara. Resulta que en React, cada vez que un componente se re-renderiza, TODAS las funciones se crean de nuevo. Sí, leíste bien. Es como si cada vez que pestañeas, tu cerebro olvidara cómo caminar y tuviera que aprenderlo de nuevo.
// Sin useCallback - Se crea una nueva función en cada render
const handleClick = () => {
console.log("Click");
};
// Con useCallback - La función se memoriza
const handleClick = useCallback(() => {
console.log("Click");
}, []); // Las dependencias van aquí
La primera vez que me explicaron esto, mi respuesta fue: "¿En serio? ¿JavaScript no puede recordar una maldita función?". Aparentemente no. Es como si JavaScript tuviera Alzheimer selectivo.
El truco está en las dependencias (ese array al final). Si está vacío, la función se crea una vez y ya. Si tiene valores, se recrea cuando esos valores cambian. Suena simple hasta que olvidas una dependencia y pasas 3 horas debuggeando por qué tu función usa valores antiguos.
useMemo: El hermano paranoico de useCallback
Si useCallback es para funciones, useMemo es para valores. Es básicamente React diciéndote: "Oye, ese cálculo es caro, ¿qué tal si no lo hacemos 50 veces por segundo?"
// Sin useMemo - Se calcula en cada render
const numerosPrimos = calcularPrimosHasta(1000000); // RIP CPU
// Con useMemo - Se calcula solo cuando cambia el límite
const numerosPrimos = useMemo(
() => calcularPrimosHasta(limite),
[limite]
);
En mi dashboard, tenía una tabla con 500 productos. Cada producto tenía cálculos de inventario, precios con descuento, y proyecciones. Sin useMemo, cada vez que el usuario escribía en el buscador, la página se congelaba como mi ex cuando le pedía que habláramos.
useEffect: El hook que todos usan mal (yo incluido)
useEffect es como ese amigo que siempre llega tarde a la fiesta pero insiste en que lo invites. Se ejecuta DESPUÉS del render, lo cual está bien hasta que no lo está.
// Mi primer useEffect (no se rían)
useEffect(() => {
// Fetch data
// Update state
// Fetch more data
// Update more state
// Infinite loop
// Laptop en llamas
// Cliente enojado
});
// Lo que debería haber hecho
useEffect(() => {
fetchData();
}, []); // Dependencias, maldita sea, DEPENDENCIAS
El problema con useEffect es que es demasiado fácil crear loops infinitos. Olvidas una dependencia, o peor, pones una dependencia que cambia dentro del mismo effect, y boom, felicidades, creaste un agujero negro en tu aplicación.
useRef: El hook que nadie entiende pero todos copian de StackOverflow
useRef es raro. Es como tener una variable que sobrevive a los re-renders pero que no causa re-renders cuando cambia. Es el ninja de los hooks.
const inputRef = useRef(null);
// Úsalo para acceder a elementos del DOM
const focusInput = () => {
inputRef.current.focus();
};
// O para guardar valores que no necesitan re-render
const contadorSilencioso = useRef(0);
contadorSilencioso.current++; // No re-renderiza nada
Honestamente, uso useRef principalmente para dos cosas: hacer focus en inputs y guardar el valor anterior de algo. Si hay otros usos, probablemente no los necesito o no los entiendo.
Custom Hooks: Cuando quieres sentirte pro
Después de 2 meses peleando con React, decidí crear mis propios hooks. Es como cuando aprendes a cocinar y de repente quieres inventar recetas.
// Mi primer custom hook (orgullosamente mediocre)
function useDebounce(value, delay) {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => clearTimeout(handler);
}, [value, delay]);
return debouncedValue;
}
// Usarlo para el buscador
const [busqueda, setBusqueda] = useState("");
const busquedaDebounced = useDebounce(busqueda, 500);
// Ahora no hago 50 peticiones mientras el usuario escribe
¿Es el mejor custom hook del mundo? No. ¿Funciona? Sí. ¿Lo copié de internet y lo modifiqué? También sí.
El verdadero problema: Over-optimización
Aquí viene la parte que nadie te dice: puedes volverte loco optimizando. Empiezas poniendo useCallback en una función, luego en todas, luego useMemo en cada variable, y de repente tu código parece que fue escrito por alguien con TOC.
La regla de oro que aprendí (después de sobre-optimizar como idiota): Primero haz que funcione, después mide, y SOLO entonces optimiza. No necesitas useCallback en un botón que se renderiza 2 veces. No necesitas useMemo para sumar 2 + 2.
Errores que cometí (para que tú no los cometas)
Error 1: useCallback en todas partes
Pensé que era mejor prevenir que lamentar. Terminé con un código ilegible y sin mejora de performance real.
Error 2: Olvidar las dependencias
El linter te grita, pero lo ignoras porque "yo sé lo que hago". No, no lo sabes. El linter tiene razón el 99% de las veces.
Error 3: No entender el re-rendering
Creía que cambiar una variable normal causaría un re-render. Pasé horas debuggeando por qué mi UI no se actualizaba. Spoiler: necesitaba useState.
Error 4: Pensar que React es como PHP
En PHP, ejecutas de arriba a abajo y ya. En React, todo es un ciclo, todo es reactivo, todo puede re-ejecutarse en cualquier momento. Es un paradigma diferente.
Mi setup actual (que funciona, más o menos)
Después de todo el sufrimiento, estas son mis reglas personales:
- useState para estado local simple
- useReducer cuando el estado se vuelve complejo (más de 3-4 valores relacionados)
- useCallback SOLO cuando paso funciones a componentes memoizados o las uso en dependencias
- useMemo SOLO para cálculos realmente pesados o referencias de objetos/arrays
- useEffect lo menos posible (la mayoría de las veces no lo necesitas)
- Custom hooks cuando repito la misma lógica 3 veces
La realidad sobre React en 2025
Miren, voy a ser honesto: React no es mi framework favorito. Prefiero mil veces PHP con algo de JavaScript vanilla para las interacciones. Pero React paga las cuentas, y eso es innegable.
¿Es complicado? Sí. ¿Es over-engineered para muchos proyectos? También. ¿El cliente lo pide porque leyó que Facebook lo usa? Definitivamente.
Pero también hay que admitir que cuando agarras la onda, cuando entiendes el flujo, cuando dejas de pelear contra el framework y empiezas a trabajar con él... funciona. Y funciona bien.
Mi dashboard de inventarios quedó rápido, responsivo, y el cliente quedó feliz. ¿Hubiera sido más fácil en PHP? Probablemente. ¿Hubiera sido igual de interactivo? Probablemente no.
React y yo seguimos en terapia de pareja. Algunos días nos llevamos bien, otros días quiero tirarlo por la ventana. Pero al final del día, es una herramienta más en el arsenal.
Si estás empezando con React, mi consejo es: no te obsesiones con la optimización prematura. Primero entiende cómo funciona, después preocúpate por los hooks avanzados. Y cuando algo no funcione, respira hondo, revisa las dependencias, y recuerda que hasta los seniors googolean "useEffect cleanup function" cada vez.
¿Ustedes también tienen una relación amor-odio con React? ¿O soy el único PHP developer que fue forzado a aprender hooks? Me encantaría saber que no estoy solo en este sufrimiento.
Comentarios
Comparte tu opinión
No hay comentarios aún
Sé el primero en compartir tu opinión sobre este artículo.