¿Es verdad que todas las variables de estado que se usan en la función de efecto (callback) de useEffect deben ser al mismo tiempo dependencias del mismo useEffect?
¡Esa es una de las reglas más importantes (y a menudo confusas) de React!
La respuesta corta es: Sí, es fundamentalmente cierto.
Todas las variables de estado, props y funciones declaradas dentro del componente que se utilizan dentro de la función de efecto (callback de useEffect) deben ser incluidas en el array de dependencias.
Esta es la forma en que React se asegura de que tu lógica se ejecute con los valores más recientes y correctos cada vez que sea necesario.
La Regla de la Exhaustividad de Dependencias
React sigue esta regla para prevenir errores sutiles y fugas de memoria causadas por cierres (closures) obsoletos.
¿Por qué es Necesario?
Cuando un componente se renderiza, la función useEffect captura los valores de las variables externas (state, props, etc.) que estaban presentes en ese renderizado específico.
Renderizado 1: La variable
contadores0. EluseEffectse ejecuta y capturacontador = 0.Renderizado 2: El usuario hace clic,
contadorahora es1. El componente se re-renderiza.El Problema: Si olvidaste incluir
contadoren el array de dependencias, eluseEffectno se vuelve a ejecutar. La función que capturó en el Renderizado 1 sigue creyendo quecontadores0. Esto conduce a un comportamiento incorrecto (o bug) donde el código parece operar con datos viejos.
Al incluir contador en las dependencias, le dices a React: "Cada vez que contador cambie (de 0 a 1, de 1 a 2, etc.), por favor, ejecuta este efecto de nuevo para que capture el nuevo valor."
Las Tres Excepciones (y Cómo Manejarlas)
Si bien la regla de incluir todas las dependencias es cierta, hay situaciones específicas donde puedes o debes omitir una variable, pero esto requiere aplicar otros hooks para mantener la estabilidad.
1. Variables Globales y Funciones Puras Externas
Si utilizas una variable o una función declarada fuera del componente (por ejemplo, importada de otro módulo, como Math.random() o una función pura), no tienes que incluirla en las dependencias, ya que su valor nunca cambia entre renderizados.
2. Funciones Setter de Estado
Las funciones que React te devuelve de useState (ej. setContador, setDatos) están garantizadas para ser estables por React. Nunca cambian.
| Setter | ¿Debe incluirse en useEffect? |
setNombre | No. React garantiza su estabilidad. |
3. Funciones (Callbacks)
Si utilizas una función declarada dentro del componente (como la función handleGuardar en un formulario), su referencia cambia en cada renderizado (lo que rompe la regla de dependencia).
La Solución: En lugar de ignorarla (lo que activaría la advertencia de React), debes memoizarla usando useCallback.
// Paso 1: Memoizar la función
const handleGuardar = useCallback(() => {
// Lógica que usa estado o props
}, [prop1, estadoA]); // Dependencias de la función
// Paso 2: Usarla como dependencia en el efecto
useEffect(() => {
// Suscribirse al guardar...
listener.subscribe(handleGuardar);
return () => {
listener.unsubscribe(handleGuardar);
};
}, [handleGuardar]); // 👈 La incluimos, pero su valor ya es estable.
Al envolver la función con useCallback, garantizas su estabilidad, y por lo tanto, useEffect solo se ejecuta si las dependencias subyacentes de esa función (prop1 o estadoA) realmente cambian.
Conclusión: La regla de oro es: si usas una variable dentro de useEffect, ponla en el array de dependencias. Si React te da una advertencia (lo cual es bueno, ya que te ayuda a evitar bugs), es señal de que debes memoizar esa dependencia con useCallback o useMemo para estabilizarla antes de incluirla.
No hay comentarios:
Publicar un comentario