Chapitre 12 — Rendu conditionnel
Jusqu’ici, vous avez surtout travaillé avec le state et les événements. Maintenant, on va découvrir un deuxième “pilier” de React : useEffect . useEffect sert à exécuter du code à certains moments : au chargement d’un composant, quand une valeur change, ou lors du nettoyage. On appelle cela des effets (side effects).
Plan du chapitre
- 1) Qu’est-ce qu’un “effet” ?
- 2) Pourquoi React a besoin de useEffect
- 3) La syntaxe de base
- 4) Le tableau de dépendances : la règle qui change tout
- 5) Exécuter une fois au montage (comme “au chargement”)
- 6) Exécuter quand une valeur change
- 7) Nettoyage (cleanup) : éviter les fuites
- 8) Cas pratiques : localStorage, timers
- 9) Erreurs fréquentes
- 10) Résumé (à retenir)
- 11) Exercice pratique (débutant)
1) Qu’est-ce qu’un “effet” ?
Un effet est un code qui interagit avec “l’extérieur” du rendu React. Le rendu React (le JSX) doit rester “pur” : il décrit l’UI. Un effet, lui, fait autre chose :
- appeler une API
- lire/écrire dans
localStorage - mettre en place un timer (
setInterval) - modifier le titre de la page (
document.title) - abonner/désabonner un event listener
React sépare volontairement : rendu (UI) d’un côté, effets de l’autre.
2) Pourquoi React a besoin de useEffect
Dans un composant, le code se “ré-exécute” à chaque rendu. Si vous appelez une API directement dans le corps du composant, vous risquez d’appeler l’API à chaque re-render. Ce n’est pas ce qu’on veut.
Exemple à ne pas faire
export default function App() {
// ❌ Appel direct pendant le rendu
fetch("https://example.com/api");
return <div>...</div>;
}
Ici, un re-render peut provoquer des appels multiples.
useEffect permet de contrôler quand le code doit s’exécuter.
3) La syntaxe de base
useEffect prend deux arguments :
- une fonction (le code à exécuter)
- un tableau de dépendances (optionnel mais très important)
import { useEffect } from "react";
useEffect(() => {
console.log("Effet exécuté");
}, []);
L’effet s’exécute après le rendu. React affiche d’abord l’UI, puis exécute l’effet.
4) Le tableau de dépendances : la règle qui change tout
Le tableau de dépendances indique à React quand relancer l’effet. Trois cas principaux :
A) Pas de tableau
useEffect(() => {
console.log("À chaque rendu");
});
➡️ S’exécute après chaque rendu (souvent une mauvaise idée).
B) Tableau vide []
useEffect(() => {
console.log("Une seule fois au montage");
}, []);
➡️ S’exécute une seule fois (comme “au chargement”).
C) Tableau avec dépendances
useEffect(() => {
console.log("Quand count change");
}, [count]);
➡️ S’exécute au montage, puis à chaque fois que count change.
Règle simple : si l’effet utilise une valeur (state/prop) et que vous voulez réagir à ses changements, vous devez la mettre dans les dépendances.
5) Exécuter une fois au montage (comme “au chargement”)
Exemple : définir le titre de la page une seule fois.
import { useEffect } from "react";
export default function App() {
useEffect(() => {
document.title = "Mon application React";
}, []);
return <h1>Bienvenue</h1>;
}
6) Exécuter quand une valeur change
Exemple : mettre le titre à jour quand count change.
import { useEffect, useState } from "react";
export default function App() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `Compteur : ${count}`;
}, [count]);
return (
<div>
<p>{count}</p>
<button onClick={() => setCount((c) => c + 1)}>+1</button>
</div>
);
}
Ici, l’effet s’exécute après le rendu initial, puis à chaque fois que count
7) Nettoyage (cleanup) : éviter les fuites
Certains effets mettent en place quelque chose qui doit être retiré quand le composant disparaît :
un intervalle, un abonnement, un event listener, etc.
Dans ce cas, useEffect peut retourner une fonction de nettoyage.
Exemple : setInterval
import { useEffect, useState } from "react";
export default function App() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const id = setInterval(() => {
setSeconds((s) => s + 1);
}, 1000);
// ✅ nettoyage quand le composant se démonte
return () => clearInterval(id);
}, []);
return <p>Secondes : {seconds}</p>;
}
Sans cleanup, vous risquez d’avoir des “timers fantômes” qui continuent même quand le composant n’est plus affiché.
8) Cas pratiques : localStorage, timers
A) Lire au montage
useEffect(() => {
const saved = localStorage.getItem("name");
if (saved) setName(saved);
}, []);
B) Écrire quand une valeur change
useEffect(() => {
localStorage.setItem("name", name);
}, [name]);
Exemple complet : un input contrôlé + persistance du prénom dans le navigateur.
9) Erreurs fréquentes
Mon effet tourne en boucle
Souvent, cela arrive quand l’effet modifie un state qui est dans les dépendances, et que cela déclenche une nouvelle exécution en permanence. Vérifiez vos dépendances et ce que vous mettez dans l’effet.
J’ai oublié les dépendances
Si votre effet utilise count ou name, mais que vous n’avez pas mis
la dépendance correspondante, vous risquez d’avoir un comportement “pas à jour”.
Je ne comprends pas pourquoi l’effet se déclenche
Rappelez-vous : sans tableau → à chaque rendu. Tableau vide → 1 fois. Avec dépendances → quand ça change.
10) Résumé (à retenir)
useEffectsert à exécuter des effets (API, storage, timers…).- Il s’exécute après le rendu.
- Dépendances : aucune → chaque rendu ;
[]→ 1 fois ;[x]→ quandxchange. - Le cleanup évite les fuites (interval, listeners…).
11) Exercice pratique (débutant)
Objectif : pratiquer les trois usages les plus courants de useEffect.
Partie A — Titre dynamique
- Créez un compteur.
- Avec
useEffect, mettez à jourdocument.titleavec la valeur du compteur.
Partie B — Persistance dans localStorage
- Créez un input contrôlé “Prénom”.
- Au montage, lisez
localStorage.getItem("name")et remplissez le state si une valeur existe. - Quand le prénom change, sauvegardez-le dans localStorage.
Partie C — Timer
- Créez un timer qui augmente un compteur de secondes toutes les 1 seconde.
- Ajoutez le cleanup pour arrêter l’interval si le composant disparaît.
Prochaine étape : Chapitre 13, on va apprendre à faire des appels API (fetch) proprement et afficher des données externes.