DEV Community

Cover image for 🔹 Errores comunes y soluciones (8/8)
Pedro Alvarado
Pedro Alvarado

Posted on

🔹 Errores comunes y soluciones (8/8)

📋 Tabla de contenidos

  1. useState – El fundamento del estado
  2. useEffect – Efectos secundarios y ciclo de vida
  3. useContext – Compartir estado sin props
  4. useReducer – Lógica de Estado Compleja y predecible
  5. useRef – Referencias, Almacenamiento y Escape
  6. useMemo y useCallback – Optimizando el Rendimiento
  7. Custom Hooks – Creando Lógica Reutilizable
  8. Errores Comunes y Soluciones

Esta sección resume los problemas más frecuentes que encontrarás al trabajar con Hooks, muchos de los cuales son la causa raíz de bugs difíciles de rastrear.

1. Romper las reglas de los hooks

React es estricto con estas dos reglas por una razón fundamental: React depende del orden en que se llaman los Hooks para asociar el estado y otros datos con la fibra del componente correcto.

  • ❌ No llames Hooks dentro de bucles, condicionales o funciones anidadas.
  • ❌ No llames Hooks desde funciones JavaScript normales. (Solo desde componentes de React o Custom Hooks).
// MAL ❌
if (condicion) {
  // El orden de llamada cambia, React se pierde.
  const [valor, setValor] = useState(0);
}
Enter fullscreen mode Exit fullscreen mode

Consecuencia: Errores crípticos, estado que se mezcla entre diferentes hooks, y comportamiento impredecible.
Solución: Llama siempre a los hooks en el nivel superior de tu componente. Si necesitas lógica condicional, ponla dentro del hook.

// BIEN ✅
useEffect(() => {
  if (condicion) {
    // La lógica condicional está *dentro* del hook.
    // El hook en sí se llama incondicionalmente.
  }
}, [condicion]);
Enter fullscreen mode Exit fullscreen mode

2. El estado "viejo" (Stale State) por closures

Este es el concepto más difícil pero más importante de entender. Cuando un componente se renderiza, "captura" los valores de las props y el estado de ese render específico en sus funciones (closures).

// PROBLEMA 😬
function Contador() {
  const [count, setCount] = useState(0);

  const mostrarAlerta = () => {
    // Esta función "recuerda" el valor de `count`
    // del render en que fue creada.
    alert('El contador es ' + count);
  };

  return (
    <div>
      <p>Contador: {count}</p>
      <button onClick={() => setCount(count + 1)}>+1</button>
      <button onClick={mostrarAlerta}>Mostrar Alerta</button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Si haces clic en "+1" varias veces y luego en "Mostrar Alerta", la alerta mostrará el valor de count que existía cuando se renderizó el botón, no el valor actual.

Solución 1: La Actualización Funcional
Si el nuevo estado depende del anterior, usa la forma funcional de setState. React te garantiza que siempre recibirás la versión más reciente del estado.

// Ideal para eventos o intervalos
setCount(prevCount => prevCount + 1);
Enter fullscreen mode Exit fullscreen mode

Solución 2: El Array de Dependencias
Para useEffect y useCallback, asegúrate de que todas las variables externas que usas estén en el array de dependencias. Esto garantiza que la función se "refresque" con los nuevos valores cuando cambien.

3. El infame array de dependencias

  • Omitir dependencias: Causa "stale state" porque el hook usa una versión vieja de una función o variable. El linter de React (eslint-plugin-react-hooks) es tu mejor amigo para detectar esto. ¡No lo ignores!
  • Dependencias que cambian demasiado: Si incluyes un objeto o una función que se redefine en cada render, el efecto se ejecutará constantemente.
    • Solución: Para funciones, usa useCallback. Para objetos, usa useMemo. Para dependencias de setState de un useState, puedes omitirlas, ya que React garantiza que son estables.

4. Abuso de la optimización

No envuelvas todo en useMemo y useCallback por defecto.

  • Coste: Estos hooks no son gratuitos. Añaden complejidad y consumen memoria.
  • Cuándo usarlos:
    1. Cuando pasas props a un componente hijo envuelto en React.memo.
    2. Para cálculos realmente pesados que están ralentizando tu componente.
    3. Para estabilizar una dependencia de otro hook (como useEffect).

Regla de oro: No optimices hasta que midas. Usa el Profiler de las React DevTools para encontrar cuellos de botella reales.


Recursos adicionales

Para seguir profundizando, estos son los mejores lugares a los que puedes acudir.

  1. Documentación Oficial de React (en español)

  2. Artículos y Guías Visuales

  3. Herramientas

    • React DevTools Profiler: Una extensión para el navegador indispensable para encontrar problemas de rendimiento y entender qué está causando los re-renderizados.
    • ESLint Plugin for React Hooks: Viene incluido por defecto en Create React App. Te avisará de errores comunes, especialmente con los arrays de dependencias.

¡Feliz codeo! 🚀

Top comments (0)