Le hook React useEffect est devenu une fonctionnalité populaire de la bibliothèque React depuis son introduction dans la version 16.8. Il permet aux développeurs d’effectuer des effets de bord tels que la récupération de données, la mise à jour du DOM et l’abonnement à des évènements à l’intérieur de composants fonctionnels.

Cependant, l’utilisation du hook useEffect peut parfois s’avérer délicate. Une erreur courante que les développeurs rencontrent est la suivante : « Le hook React useEffect a une dépendance manquante. Intégrez-la ou supprimez le tableau de dépendances ».

Dans cet article, nous allons discuter des causes de cette erreur et fournir diverses solutions pour la corriger.

Quelles sont les causes de l’erreur « React Hook useEffect Has a Missing Dependency » ?

L’erreur « Le hook React useEffect a une dépendance manquante » se produit lorsque le Hook useEffect a un tableau de dépendances incomplet ou manquant.

Le tableau de dépendance est le deuxième argument du hook useEffect et est utilisé pour spécifier les variables dont dépend l’effet. Cela signifie que lorsque l’une des valeurs des variables spécifiées dans le tableau de dépendance change, l’effet est ré-exécuté.

Dans le cas où une variable dont dépend l’effet n’est pas incluse dans le tableau de dépendance, l’effet peut ne pas être ré-exécuté lorsque la valeur change. Cela peut entrainer un comportement inattendu et des bogues dans votre application.

Cette erreur n’est pas une erreur React mais une erreur ESLint. ESLint fournit une extension spécifique pour React, qui inclut un ensemble de règles conçues pour aider les développeurs à écrire un meilleur code React. L’une de ces règles est la règle "react-hooks/exhaustive-deps", qui détecte l’erreur « Le hook React useEffect a une dépendance manquante ».

Prenons l’exemple d’un composant fonctionnel qui possède un état de comptage. Ce composant est également censé enregistrer un message avec la valeur de count dans la console chaque fois qu’il change :

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;

Dans l’exemple ci-dessus, vous avez un composant fonctionnel qui utilise les crochets useState et useEffect. Le crochet useEffect est utilisé pour enregistrer un message avec la valeur de la variable d’état count chaque fois qu’elle change.

Cependant, remarquez que la variable count n’est pas listée dans le second tableau d’arguments (tableau de dépendances) du hook useEffect. Cela déclenchera l’erreur « Le hook React useEffect a une dépendance manquante ».

Message d'erreur
Message d’erreur « React Hook useEffect has a missing dependency » (Le crochet React useEffect a une dépendance manquante)

3 façons de corriger l’erreur « React Hook useEffect Has a Missing Dependency » (Le crochet React useEffect a une dépendance manquante)

Cette erreur peut être corrigée de différentes manières en fonction de l’approche que vous souhaitez utiliser. Voici les différentes manières.

  • Inclure toutes les dépendances manquantes
  • Utilisez des crochets de mémorisation lorsque vous travaillez avec des objets et des fonctions
  • Désactiver la règle ESLint

1. Ajoutez la dépendance manquante au tableau de dépendances useEffect

La façon la plus simple de résoudre cette erreur est d’inclure toutes les dépendances utilisées dans le crochet useEffect dans le tableau de dépendances. Vous pouvez alors vous demander comment reconnaître une dépendance ?

Pour identifier une dépendance manquante, vous devez examiner les variables ou les valeurs utilisées dans le crochet useEffect. Si l’une de ces variables ou valeurs peut changer au fil du temps, elle doit être incluse dans le tableau des dépendances.

Par exemple, dans l’extrait de code fourni précédemment, la variable count est utilisée dans le crochet useEffect, mais elle n’est pas incluse dans le tableau de dépendance. Cela signifie que si la variable count change, le crochet useEffect ne sera pas réexécuté et le composant peut avoir des données périmées ou d’autres problèmes.

Pour corriger cette erreur, nous pouvons ajouter la variable count au tableau des dépendances, comme suit :

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;

En ajoutant la variable count au tableau de dépendances, nous indiquons à React de réexécuter le hook useEffect chaque fois que la variable count change.

Cela garantit que le composant dispose toujours de données à jour et évite l’erreur « React Hook useEffect has a missing dependency » (le crochet React useEffect a une dépendance manquante).

Si vous avez plus d’une dépendance, ajoutez-les dans le tableau de dépendances et séparez-les par une virgule :

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. Travailler avec des objets et des fonctions

Lorsque vous travaillez avec des objets et des tableaux, il ne suffit pas de les ajouter à votre tableau de dépendances, vous devrez soit les mémoriser, soit les déplacer dans le hook useEffect ou en dehors du composant pour éviter les re-rendus inutiles.

En effet, en JavaScript, les objets et les tableaux sont comparés par référence et pointent à chaque fois vers un emplacement différent dans la mémoire – leur valeur changera à chaque rendu, ce qui entrainera une boucle de re-rendu infinie.

Voici un exemple qui provoque l’erreur :

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;

Vous pouvez corriger cette erreur en déplaçant l’objet dans le hook useEffect ou en le déplaçant en dehors du composant :

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;

Une meilleure façon de résoudre ce problème est d’utiliser des hooks de mémorisation comme useMemo pour votre objet et useCallback pour les fonctions. Cela vous aidera à conserver l’objet ou la fonction dans le composant et dans le tableau des dépendances.

Remarque : les hooks de mémorisation sont un ensemble de hooks qui vous permettent de mettre en cache les résultats de calculs couteux et d’éviter de les recalculer inutilement.

Voici à quoi ressemblera votre code lorsque vous utiliserez le hook useMemo pour mémoriser votre objet :

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;

De même, lorsque vous travaillez avec des fonctions, vous pouvez utiliser le hook useCallback.

3. Désactiver la règle ESLint

L’erreur « Le hook React useEffect a une dépendance manquante » est une erreur d’avertissement ESLint – ce qui signifie que nous pouvons désactiver la règle pour qu’elle ne génère pas l’erreur. Cette approche n’est pas recommandée dans tous les cas, mais elle peut être une solution rapide si vous êtes certain que la dépendance manquante n’est pas un problème.

Pour ce faire, ajoutez le commentaire suivant avant la ligne du tableau de dépendances.

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

Voici un exemple :

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

Il est important de noter que la désactivation de la règle ESLint peut entrainer d’autres problèmes à l’avenir si vous ne faites pas attention. Assurez-vous de bien comprendre les conséquences de la désactivation d’une règle avant de le faire et envisagez d’autres solutions si possible.

Résumé

L’erreur « Le hook React useEffect a une dépendance manquante » est un problème courant rencontré par les développeurs React lorsqu’ils travaillent avec le hook useEffect.

Lorsque vous corrigez l’erreur, il est important de considérer les meilleures méthodes pour votre cas d’utilisation spécifique. En général, il est préférable d’éviter de désactiver la règle ESLint à l’origine de l’erreur, car cela peut entrainer d’autres problèmes à l’avenir. Essayez plutôt de résoudre le problème en incluant la dépendance manquante dans le tableau de dépendances ou en utilisant le bon hook de mémorisation.

À vous de jouer : Avez-vous déjà rencontré ce problème ? Comment l’avez-vous résolu ? Y a-t-il d’autres approches que vous avez utilisées et qui ne sont pas abordées dans cet article ? Faites-nous en part dans les commentaires !