Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 3

Exécuter du code au montage avec useEffect

Recommended resources

Bonjour ! Dans la leçon précédente, nous avons découvert le hook useState, qui permet à nos composants de "se souvenir" d'informations et de réagir aux actions de l'utilisateur. C'est un grand pas vers l'interactivité.

Introduction

Aujourd'hui, nous allons nous intéresser à une autre facette de l'interactivité : comment un composant peut-il réagir non pas à un clic, mais à son propre cycle de vie, comme son apparition à l'écran ? C'est le rôle du hook useEffect.

Notre objectif est précis : utiliser le hook useEffect pour exécuter du code au montage d'un composant. "Monter" un composant signifie simplement le moment où React le crée et l'ajoute à la page pour la première fois.

Cette compétence est fondamentale pour nos futurs projets 3D. C'est grâce à elle que nous pourrons, par exemple, initialiser une scène Three.js, charger un modèle 3D ou lancer une animation dès que notre canevas 3D apparaît.

À la fin de cette leçon, vous saurez :

  • Ce qu'est un "effet de bord" et pourquoi il nécessite un hook dédié.
  • Comment utiliser useEffect avec un "tableau de dépendances" vide pour exécuter du code une seule et unique fois.
  • L'importance de la fonction de "nettoyage" pour éviter les fuites de mémoire.

1. Qu'est-ce qu'un "effet de bord" ?

Dans l'univers React, on distingue trois types de logique dans un composant :

  1. Le code de rendu : Il calcule le JSX. Il doit être "pur", comme une formule mathématique qui donne toujours le même résultat pour les mêmes entrées.
  2. Les gestionnaires d'événements : Ce sont les fonctions qui s'exécutent en réponse à une action de l'utilisateur (ex: onClick).
  3. Les effets de bord (Side Effects) : Ce sont toutes les autres interactions avec le monde extérieur à React. Cela inclut la manipulation directe du DOM, les appels réseau (API), l'abonnement à des services, ou la mise en place de setInterval.

Les effets de bord ne doivent se produire ni pendant le rendu (qui doit rester pur), ni forcément en réponse à un clic. Ils sont souvent liés au rendu lui-même. C'est là que useEffect intervient : il nous permet de déclencher ces effets de bord après que React ait mis à jour l'écran.

Pour mieux visualiser où se situe useEffect dans le cycle de vie d'un composant, examinons ce schéma.

React Hooks Lifecycle Diagram
Ce diagramme illustre les phases de "Render" (rendu) et "Commit" (application) dans React. `useEffect` s'exécute pendant la phase de "Commit", après que les changements ont été appliqués au DOM.

Comme vous pouvez le voir, useEffect se déclenche après la phase de rendu, ce qui garantit que le DOM est bien à jour et prêt à être manipulé.


2. useEffect : Exécuter du code au montage

La syntaxe de base de useEffect est un appel de fonction qui prend une autre fonction en argument.

import { useEffect } from 'react';

useEffect(() => {
  // Ce code s'exécute après CHAQUE rendu du composant.
  console.log('Le composant a été rendu.');
});

Ce comportement par défaut est rarement celui que l'on souhaite. Si l'effet modifie un état avec useState, il va déclencher un nouveau rendu, qui va ré-exécuter l'effet, qui va remodifier l'état... créant une boucle infinie !

Pour contrôler quand l'effet doit s'exécuter, on lui passe un second argument : le tableau de dépendances.

  • useEffect(maFonction) : S'exécute après chaque rendu.
  • useEffect(maFonction, [prop, etat]) : S'exécute au montage, puis uniquement si prop ou etat changent.
  • useEffect(maFonction, []) : S'exécute uniquement au montage.

C'est cette dernière syntaxe, avec le tableau vide [], qui nous permet d'atteindre notre objectif du jour.

La vidéo suivante illustre parfaitement le problème de la boucle infinie et comment le tableau de dépendances vide le résout.

Comprendre le hook useEffect de React

Cette vidéo de la chaîne Atomic React explique de manière très claire le cycle de vie d'un composant et comment utiliser useEffect pour n'exécuter du code qu'au montage.

Regardez ces deux parties : Le cycle de vie d'un composant (00:25 - 03:30) : Pour bien comprendre les termes "montage", "mise à jour" et "démontage". Le tableau de dépendances vide (05:55 - 09:25) : Pour voir le problème de la boucle infinie et comment le tableau [] le résout pour n'exécuter l'effet qu'une seule fois.


3. Le nettoyage : une étape indispensable

Que se passe-t-il si notre effet de montage démarre un processus continu, comme un setInterval ou une connexion à un serveur ? Si le composant est "démonté" (retiré de l'écran), ce processus va continuer à tourner en arrière-plan, consommant de la mémoire inutilement. C'est ce qu'on appelle une "fuite de mémoire".

Pour éviter cela, useEffect nous permet de retourner une fonction de nettoyage. React exécutera cette fonction juste avant de démonter le composant.

useEffect(() => {
  console.log('Effet de montage : le timer démarre !');
  const intervalId = setInterval(() => {
    console.log('Tick');
  }, 1000);

  // La fonction de nettoyage
  return () => {
    console.log('Nettoyage : le timer est arrêté.');
    clearInterval(intervalId);
  };
}, []); // Tableau vide = s'exécute au montage, se nettoie au démontage.

La vidéo que nous avons commencée explique très bien ce mécanisme.

Comprendre le hook useEffect de React

Continuons avec la vidéo d'Atomic React pour comprendre la fonction de nettoyage.

Regardez la partie sur la fonction de nettoyage, de 09:36 à 14:00. L'exemple avec setInterval est un cas d'école.

Une particularité du mode développement

Vous remarquerez peut-être dans votre console que l'effet s'exécute deux fois au démarrage : montage -> nettoyage -> montage. Ce n'est pas un bug ! En mode développement, React monte, démonte, puis remonte intentionnellement vos composants pour vérifier que votre fonction de nettoyage fonctionne correctement. Cela vous aide à détecter les fuites de mémoire très tôt. En production, l'effet ne s'exécutera qu'une seule fois.

Pour une explication détaillée, la documentation officielle est votre meilleure alliée.

Synchroniser grâce aux Effets - React

La documentation officielle de React explique en détail le concept de nettoyage et le comportement de useEffect en mode développement. C'est une lecture importante pour solidifier vos connaissances.

Lisez les sections "Étape 3 : ajoutez du code de nettoyage si besoin" et "Comment gérer le double déclenchement de l’Effet en développement ?".


4. Cas d'usage : Aller chercher des données

Un des usages les plus courants de useEffect au montage est de faire un appel à une API pour récupérer les données initiales à afficher dans le composant.

import { useState, useEffect } from 'react';

function UserProfile({ userId }) {
  const [user, setUser] = useState(null);

  useEffect(() => {
    // On définit une fonction asynchrone à l'intérieur de l'effet
    const fetchUser = async () => {
      const response = await fetch(`https://api.example.com/users/${userId}`);
      const data = await response.json();
      setUser(data);
    };

    fetchUser(); // On l'appelle
  }, []); // Tableau vide pour ne le faire qu'au montage

  if (!user) {
    return <div>Chargement...</div>;
  }

  return <h1>{user.name}</h1>;
}

Ce modèle est extrêmement répandu. La vidéo suivante le met en pratique.

Comprendre le hook useEffect de React

Pour finir avec la vidéo d'Atomic React, voyons un exemple concret d'appel à une API.

Regardez la partie sur la récupération de données, de 19:39 à 23:07. Notez bien l'utilisation du tableau de dépendances vide pour éviter des appels répétés à l'API.


5. Exercice pratique : Mettre le focus sur un champ de saisie

Mettons cela en pratique. L'objectif est de faire en sorte qu'un champ de saisie obtienne automatiquement le "focus" (le curseur se place dedans) dès qu'il apparaît à l'écran. C'est une tâche de manipulation du DOM parfaite pour useEffect.

Pour accéder directement à un élément du DOM comme <input>, nous avons besoin d'un autre hook, useRef, que nous étudierons en détail dans la prochaine leçon. Pour cet exercice, considérez-le simplement comme un moyen d'obtenir une référence à l'élément.

Votre mission : Complétez le code ci-dessous pour que ref.current.focus() soit appelé au bon moment, c'est-à-dire uniquement au montage du composant MyInput.

// Code de départ
import { useEffect, useRef } from 'react';

export default function MyInput({ value, onChange }) {
  const ref = useRef(null);

  // TODO: Ajoutez un useEffect ici pour que l'appel ci-dessous
  // s'exécute uniquement au montage du composant.
  // ref.current.focus();

  return <input ref={ref} value={value} onChange={onChange} />;
}
Cliquez ici pour voir la solution
import { useEffect, useRef } from 'react';

export default function MyInput({ value, onChange }) {
  const ref = useRef(null);

  // La solution : on enveloppe l'appel dans un useEffect
  // avec un tableau de dépendances vide.
  useEffect(() => {
    ref.current.focus();
  }, []);

  return <input ref={ref} value={value} onChange={onChange} />;
}

Cet exercice, tiré de la documentation de React, est un excellent exemple de synchronisation avec un système externe (le DOM) au montage du composant.


Conclusion

Félicitations ! Vous maîtrisez maintenant le mécanisme pour déclencher des actions au moment précis où vos composants prennent vie.

Les points clés à retenir :

  • useEffect sert à gérer les effets de bord (appels API, manipulation du DOM, timers...).
  • Il s'exécute après le rendu et la mise à jour de l'écran.
  • Un tableau de dépendances vide [] est la clé pour n'exécuter un effet qu'une seule fois, au montage du composant.
  • La fonction de nettoyage retournée par l'effet est cruciale pour éviter les fuites de mémoire, notamment pour les processus qui continuent après le montage.

Dans la prochaine leçon, nous plongerons dans le hook useRef. Nous l'avons entraperçu aujourd'hui : c'est notre outil pour obtenir une référence stable vers des éléments du DOM (comme le <canvas> de notre future scène 3D) ou pour stocker des valeurs qui ne doivent pas déclencher de nouveau rendu. C'est le partenaire idéal de useEffect pour de nombreuses applications interactives.