El Hook React useEffect se ha convertido en una función popular de la biblioteca React desde su introducción en la versión 16.8. Permite a los desarrolladores realizar efectos secundarios como obtener datos, actualizar el DOM y suscribirse a eventos dentro de componentes funcionales.

Sin embargo, el Hook useEffect a veces puede ser difícil de usar. Un error común que encuentran los desarrolladores es el «React Hook useEffect has a missing dependency. Either include it or remove the dependency array» (Falta una dependencia de React Hook useEffect. Inclúyela o elimina del array de dependencias).

En este artículo, discutiremos las causas de este error y proporcionaremos varias soluciones sobre cómo solucionarlo.

¿Qué Causa el Error «React Hook useEffect Has a Missing Dependency»?

El error «React Hook useEffect has a missing dependency» se produce cuando el Hook useEffect tiene un array de dependencias que está incompleto o falta.

El array de dependencia es el segundo argumento del Hook useEffect y se utiliza para especificar las variables de las que depende el efecto. Esto significa que cuando cambia alguno de los valores de las variables especificadas en el array de dependencias, el efecto se vuelve a ejecutar.

Si una variable de la que depende el efecto no está incluida en el array de dependencias, es posible que el efecto no se vuelva a ejecutar cuando cambie su valor. Esto puede provocar un comportamiento inesperado y errores en tu aplicación.

Este error no es un error de React, sino un error de ESLint. ESLint proporciona un plugin específico para React, que incluye un conjunto de reglas diseñadas para ayudar a los desarrolladores a escribir mejor código React. Una de estas reglas es la regla "react-hooks/exhaustive-deps", que detecta el error «React Hook useEffect has a missing dependency».

Como ejemplo, veamos un componente funcional que tiene un estado de recuento. También se espera que este componente registre un mensaje con el valor de count en la consola cada vez que cambie:

import { useState, useEffect } from 'react';

const App = () => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log(`You clicked ${count} times`);
  }, []);

  return (
    <div>
      <h1>Hello World</h1>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
};

export default App;

En el ejemplo anterior, tienes un componente funcional que utiliza los hooks useState y useEffect. El hook useEffect se utiliza para registrar un mensaje con el valor de la variable de estado count cada vez que cambia.

Sin embargo, observa que la variable count no aparece en el segundo array de argumentos (array de dependencias) del hook useEffect. Esto provocará el error «React Hook useEffect has a missing dependency».

React Hook useEffect tiene un mensaje de error de falta de dependencia
React Hook useEffect tiene un mensaje de error de falta de dependencia

3 Formas de Solucionar el Error «React Hook useEffect Has a Missing Dependency»

Este error puede solucionarse de diferentes maneras, dependiendo del enfoque que desees utilizar. Aquí tienes las distintas formas.

  • Incluir todas las dependencias que faltan
  • Utilizar hooks de memoización cuando trabajes con objetos y funciones
  • Desactivar la regla ESLint

1. Añade la Dependencia que Falta al Array de Dependencias useEffect

La forma más sencilla de resolver este error es incluir todas las dependencias utilizadas en el hook useEffect en el array de dependencias. Entonces te preguntarás ¿cómo puedo conocer una dependencia?

Para identificar una dependencia que falta, tienes que fijarte en las variables o valores que se utilizan dentro del hook useEffect. Si alguna de estas variables o valores puede cambiar con el tiempo, entonces debe incluirse en el array de dependencias.

Por ejemplo, en el fragmento de código proporcionado anteriormente, la variable count se utiliza dentro del hook useEffect, pero no se incluye en el array de dependencia. Esto significa que si la variable count cambia, el hook useEffect no se volverá a ejecutar, y el componente puede tener datos obsoletos u otros problemas.

Para solucionar este error, podemos añadir la variable count al array de dependencias, de la siguiente manera:

import { useState, useEffect } from 'react';

const App = () => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log(`You clicked ${count} times`);
  }, [count]);

  return (
    <div>
      <h1>Hello World</h1>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
};

export default App;

Al añadir la variable count al array de dependencias, le decimos a React que vuelva a ejecutar el hook useEffect siempre que cambie la variable de recuento.

Esto garantiza que el componente siempre tenga datos actualizados y evita el error “React Hook useEffect has a missing dependency”.

Si tienes más de una dependencia, añádelas al array de dependencias y sepáralas con una coma:

import { useState, useEffect } from 'react';
const App = () => {
  const [firstName, setFirstName] = useState('');
  const [lastName, setLastName] = useState('');
  const [fullName, setFullName] = useState('');

  useEffect(() => {
    setFullName(`${firstName} ${lastName}`);
  }, [firstName, lastName]);

  const handleFirstNameChange = (event) => {
    setFirstName(event.target.value);
  };

  const handleLastNameChange = (event) => {
    setLastName(event.target.value);
  };

  return (
    <div>
      <label>
        First Name:
        <input type="text" value={firstName} onChange={handleFirstNameChange} />
      </label>
      <label>
        Last Name:
        <input type="text" value={lastName} onChange={handleLastNameChange} />
      </label>
      <p>Full Name: {fullName}</p>
    </div>
  );
};

export default App;

2. Trabajar con Objetos y Funciones

Cuando trabajes con objetos y Arrays, no basta con añadirlos a tu array de dependencias, tendrás que memoizarlos o moverlos al hook useEffect o fuera del componente para evitar repeticiones innecesarias.

Esto se debe a que, en JavaScript, los objetos y arrays se comparan por referencia y apuntan a una ubicación diferente en la memoria cada vez — su valor cambiará en cada renderización, provocando un bucle infinito de re-renderización.

Aquí tienes un ejemplo que provoca el error:

import { useState, useEffect } from 'react';

const App = () => {
  const [user, setUser] = useState({});

  // 👇️this will change on every render
  let newUser = { name: 'Jane', age: 28 };

  useEffect(() => {
    setUser(newUser);
  }, [newUser]);

  return (
    <div>
      <h1>Hello World</h1>
    </div>
  );
};

export default App;

Puedes solucionar este error moviendo el objeto al hook useEffect o moviéndolo fuera del componente:

import { useState, useEffect } from 'react';

const App = () => {
  const [user, setUser] = useState({});

  useEffect(() => {
    let newUser = { name: 'Jane', age: 28 };
    setUser(newUser);
  }, []);

  return (
    <div>
      <h1>Hello World</h1>
    </div>
  );
};

export default App;

Una forma mejor de resolver este problema es utilizar hooks de memoización como useMemo para tu objeto y useCallback para las funciones. Esto te ayudará a conservar el objeto o la función dentro del componente y en el array de dependencias.

Nota: Los hooks de memoización son un conjunto de hooks que te permiten almacenar en caché los resultados de cálculos costosos y evitar volver a calcularlos innecesariamente.

Este es el aspecto que tendrá tu código cuando utilices el hook useMemo para memoizar tu objeto:

import { useState, useEffect, useMemo } from 'react';

const App = () => {
  const [user, setUser] = useState({});

  const newUser = useMemo(() => {
    return { name: 'John', age: 30 };
  }, []);

  useEffect(() => {
    setUser(newUser);
  }, [newUser]);

  return (
    <div>
      <h1>Hello World</h1>
    </div>
  );
};

export default App;

Del mismo modo, cuando trabajes con funciones, puedes utilizar el hook useCallback.

3. Desactiva la Regla ESLint

El error «React Hook useEffect has a missing dependency» es un error de advertencia de ESLint, lo que significa que podemos desactivar la regla para que no lance el error. Este método no se recomienda en todos los casos, pero puede ser una solución rápida si estás seguro de que la dependencia que falta no es un problema.

Para ello, añade el siguiente comentario antes de la línea del array de dependencias.

// eslint-disable-next-line react-hooks/exhaustive-deps

Aquí tienes un ejemplo:

useEffect(() => {
  console.log(`You clicked ${count} times`);
  
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

Es importante tener en cuenta que desactivar la regla ESLint puede provocar otros problemas en el futuro si no tienes cuidado. Asegúrate de que comprendes bien las consecuencias de desactivar una regla antes de hacerlo y considera soluciones alternativas si es posible.

Resumen

El error «React Hook useEffect has a missing dependency» es un problema común al que se enfrentan los desarrolladores de React cuando trabajan con el hook useEffect.

A la hora de solucionar el error, es importante tener en cuenta los mejores métodos para tu caso de uso específico. En general, es mejor evitar desactivar la regla de ESLint que causa el error, ya que esto puede dar lugar a otros problemas en el futuro. En su lugar, intenta solucionar el problema incluyendo la dependencia que falta en el array de dependencias o utilizando el hook de memoización adecuado.

Ahora te toca a ti: ¿Te has encontrado alguna vez con este problema? ¿Cómo lo resolviste? ¿Hay algún otro método que hayas utilizado y que no se haya tratado en este artículo? ¡Háznoslo saber en los comentarios!