Aller au contenu principal
Dev Serein
Retour aux solutions
FrontendIntermédiaire

React : arrêter une boucle infinie dans useEffect

Repérer l’état et la dépendance qui relancent un effet, puis corriger le flux de données sans masquer la cause.

Un effet boucle lorsqu’il modifie un état, que cet état déclenche un rendu, puis qu’une dépendance de l’effet change encore à ce rendu. Le message Maximum update depth exceeded peut en être le symptôme. Deux exécutions au montage en développement ne prouvent pas une boucle : React Strict Mode vérifie aussi le nettoyage des effets.

Reproduire et trouver le cycle

Repérez l’effet qui appelle setState et les valeurs dans son tableau de dépendances. Dans React DevTools, observez quels composants se rendent à répétition. Ajoutez temporairement un journal pour voir la valeur qui change, puis retirez-le une fois le diagnostic terminé.

Symptôme Cause à vérifier
L’effet tourne après chaque rendu Tableau de dépendances absent
L’effet tourne malgré un tableau Objet ou fonction recréé à chaque rendu
L’effet modifie une de ses dépendances Mise à jour qui entretient elle-même le cycle
Deux appels au montage, puis plus rien Vérification de Strict Mode en développement

Supprimer l’effet s’il ne synchronise rien d’externe

Un calcul basé uniquement sur des props ou un état existant peut se faire pendant le rendu :

function Liste({ items, filtre }: { items: string[]; filtre: string }) {
  const visibles = items.filter((item) => item.includes(filtre));
  return <ul>{visibles.map((item) => <li key={item}>{item}</li>)}</ul>;
}

Stocker aussi visibles dans un état, puis le recalculer dans un effet, ajoute un rendu et deux valeurs à maintenir cohérentes. Une optimisation avec useMemo ne devient utile que si le calcul est coûteux et mesuré.

Stabiliser une vraie dépendance

Ici, options est un nouvel objet à chaque rendu. Si l’effet met à jour un état utilisé par le composant, cela peut provoquer des relances inutiles :

// À éviter : l'objet change d'identité à chaque rendu.
const options = { roomId };
useEffect(() => {
  const connection = createConnection(options);
  connection.connect();
  return () => connection.disconnect();
}, [options]);

Pour un système externe comme une connexion, construisez l’objet dans l’effet et dépendez de la valeur primitive réellement utilisée :

useEffect(() => {
  const connection = createConnection({ roomId });
  connection.connect();
  return () => connection.disconnect();
}, [roomId]);

Cet extrait suppose que createConnection existe dans votre application. Ne retirez pas roomId du tableau pour faire taire le lint : l’effet doit se reconnecter quand cette valeur change. Le nettoyage est nécessaire lorsque le composant se démonte ou que roomId change.

Vérifier une mise à jour d’état intentionnelle

Si l’effet reçoit des données externes, demandez-vous si la mise à jour produit réellement une nouvelle valeur. Une mise à jour répétée avec un objet neuf, même de contenu identique, peut entretenir des rendus. Comparez la donnée utile avant de mettre à jour l’état ou déplacez la transformation dans le calcul de rendu.

Ne remplacez pas automatiquement une dépendance par []. Cela peut laisser l’effet connecté à d’anciennes props. useCallback et useMemo peuvent stabiliser certaines références, mais commencez par simplifier la logique et déplacer les objets temporaires dans l’effet.

Confirmer la correction

Testez le montage, un changement réel de dépendance et le démontage. Vérifiez que l’effet s’exécute quand il le doit, que son nettoyage fonctionne et que le rendu ne se répète plus sans raison. En développement sous Strict Mode, un cycle supplémentaire de configuration et nettoyage au montage reste normal.

Ressources

SUPER CALCULATEUR / CONNEXION ÉTABLIE

UN PASSAGE SECRET DANS DEV SEREIN

Bienvenue sur
Code Lyoko.

Le monde virtuel n’était qu’à quelques lettres.
Jérémie a ouvert la connexion. À toi de jouer.

Des arbres infinis, des chemins suspendus. Garde un œil sur la mer numérique.

LYOKO-GUERRIERS

Aelita · Yumi · Ulrich · Odd

SCAN DU TERRITOIREFORÊT / 01

ALERTE XANA · TOUR ACTIVÉE

On compte sur toi, Aelita.