useEffect et boucle infinie
Pourquoi j'ai une boucle infinie dans mon useEffect ?
🔄 Pourquoi en React, l’ajout de dépendances dans useEffect peut provoquer une boucle infinie
Lorsque vous travaillez avec React, il est fréquent d'utiliser le hook useEffect pour gérer des effets secondaires tels que :
- 🌐 Les requêtes réseau,
- 📡 Les abonnements à des événements,
- 🖱️ La mise à jour de l'état.
Cependant, l’ajout de certaines dépendances dans le tableau de dépendances de useEffect, comme recommandé par le linter, peut parfois conduire à une boucle infinie.
Cet article explique pourquoi cela se produit et comment éviter ce problème.
1️⃣ Le fonctionnement de useEffect
useEffect est utilisé pour exécuter du code après le rendu du composant. Vous pouvez le configurer pour s'exécuter uniquement lors du premier rendu (en fournissant une liste de dépendances vide), ou chaque fois que certaines variables changent.
Voici la structure générale de useEffect :
Le tableau des dépendances détermine quand l'effet doit être exécuté :
- Si le tableau est vide (
[]), l’effet ne s’exécute qu’une seule fois 🏁. - Si vous passez des variables dans le tableau (
[var1, var2]), l’effet s’exécutera chaque fois que l'une de ces variables change 🔄.
2️⃣ Le rôle du linter 🔍
Les linters, comme ESLint, suggèrent souvent d’ajouter des variables utilisées dans votre useEffect pour garantir que l'effet reflète correctement les changements de ces variables. Cela permet de maintenir le code cohérent et à jour.
Cependant, suivre aveuglément ces recommandations peut parfois provoquer des boucles infinies, où useEffect est ré-exécuté sans cesse.
Mais alors au lieu de juste faire ça :
.......si si, on vous voit 👀
Essayons de comprendre, au moins en surface, pourquoi j'ai une boucle infinie et comment l'éviter.
3️⃣ Pourquoi l’ajout de dépendances peut provoquer une boucle infinie 🌀
a. Les fonctions ou objets redéfinis à chaque rendu 🚨
En React, les fonctions et objets définis à l'intérieur d'un composant sont recréés à chaque rendu. Si vous les incluez comme dépendances, l’effet sera ré-exécuté sans cesse, car la référence change constamment.
Exemple problématique :
b. Les états mis à jour dans useEffect
Mettre à jour un état avec setState dans un useEffect déclenche un nouveau rendu. Si cet état est inclus dans la liste des dépendances, cela provoque une boucle infinie, car le rendu relance l'effet, qui à son tour modifie l'état.
Exemple :
4️⃣ Comment éviter les boucles infinies ✅
a. Utiliser useCallback ou useMemo pour stabiliser les références
Utilisez useCallback pour stabiliser une fonction ou useMemo pour stabiliser un objet, afin d'éviter qu'ils soient recréés à chaque rendu.
b. Ne pas inclure les états mis à jour dans useEffect
Évitez d'inclure des états qui sont mis à jour par l’effet dans la liste des dépendances, sauf si c'est absolument nécessaire.
c. Analyser la logique métier 🧠
Assurez-vous que l'effet doit réellement se déclencher à chaque changement de certaines variables. Sinon, ajustez la liste des dépendances pour n'inclure que les variables nécessaires.
d. Utiliser des conditions dans useEffect
Ajoutez des conditions dans votre effet pour contrôler son exécution.
🚀 Conclusion
Les boucles infinies dans useEffect proviennent souvent de dépendances instables (comme des fonctions ou des objets recréés à chaque rendu) ou de la mise à jour d’états surveillés inutilement. Pour éviter ces erreurs tout en respectant les recommandations du linter, stabilisez vos références avec useCallback ou useMemo, et gérez soigneusement vos dépendances dans useEffect.