Kodokon kodokon.com

useEffect : effets, dépendances, nettoyage

Synchronisez vos composants avec le monde extérieur grâce à useEffect, en maîtrisant les dépendances et le nettoyage.

9 min · 3 questions

Ouvrir cette leçon dans Kodokon

Un composant React calcule du JSX à partir de props et d'état. Tout ce qui sort de ce cadre - modifier le titre du document, lancer un minuteur, s'abonner à un événement du navigateur - est un effet de bord. useEffect exécute ce code après le rendu, sans bloquer l'affichage, et le resynchronise quand certaines valeurs changent.

JSX
import { useEffect } from "react";

function CartTitle({ count }) {
  useEffect(() => {
    document.title = `Panier (${count})`;
  }, [count]);

  return <p>Articles : {count}</p>;
}
L'effet se rejoue uniquement quand count change.

Le tableau de dépendances pilote la fréquence d'exécution. [count] : l'effet se rejoue après chaque rendu où count a changé. [] : l'effet ne s'exécute qu'une fois, après le premier rendu. Tableau absent : l'effet se rejoue après chaque rendu, ce qui est rarement souhaitable. Règle d'or : toute valeur du composant utilisée dans l'effet doit figurer dans le tableau.

JSX
import { useEffect, useState } from "react";

function Timer() {
  const [seconds, setSeconds] = useState(0);

  useEffect(() => {
    const id = setInterval(() => {
      setSeconds((s) => s + 1);
    }, 1000);

    return () => clearInterval(id);
  }, []);

  return <p>Écoulé : {seconds} s</p>;
}
Sans clearInterval, le minuteur survivrait au composant.

La fonction retournée par l'effet est la fonction de nettoyage. React l'appelle avant chaque nouvelle exécution de l'effet, puis une dernière fois au démontage du composant. C'est elle qui évite les fuites : minuteurs orphelins, écouteurs empilés, abonnements jamais résiliés. Chaque effet qui « ouvre » quelque chose doit le refermer.

JSX
useEffect(() => {
  function onResize() {
    setWidth(window.innerWidth);
  }
  window.addEventListener("resize", onResize);

  return () => {
    window.removeEventListener("resize", onResize);
  };
}, []);
Abonnement à l'événement resize, résilié au démontage.

Quiz de validation

Vérifiez que vous avez bien retenu les points clés de cette leçon.

  1. Avec useEffect(fn, []), quand la fonction fn est-elle exécutée ?
    • Avant chaque rendu du composant
    • Après le premier rendu uniquement
    • À chaque mise à jour de l'état
  2. Quand la fonction de nettoyage retournée par un effet est-elle appelée ?
    • Uniquement quand le composant est démonté
    • Avant chaque ré-exécution de l'effet et au démontage
    • Juste avant le premier rendu du composant
    • Jamais automatiquement : il faut l'appeler soi-même
  3. Un effet lit userId mais son tableau de dépendances est []. Quel est le problème ?
    • L'effet ne se relancera pas quand userId change et gardera une valeur périmée
    • React lèvera une erreur dès le premier rendu
    • L'effet se rejouera en boucle infinie