Join the discussion
Comments
Loading comments...
Cookie preferences
We use essential cookies for sign-in and preferences. With your permission, we also use basic analytics to improve lessons.
Join the discussion
Loading comments...
We use essential cookies for sign-in and preferences. With your permission, we also use basic analytics to improve lessons.
Phases de montage, mise à jour et démontage — voyez quels hooks et effets se déclenchent à chaque étape.
Chaque composant React passe par trois phases de cycle de vie : le Montage (premier rendu dans le DOM), la Mise à Jour (re-rendus dus aux changements de state ou de props) et le Démontage (retrait du DOM). Avec les hooks, ces phases s'expriment via useEffect, useLayoutEffect et les fonctions de nettoyage plutôt que par des méthodes de cycle de vie de classe.
React appelle votre fonction composant, évalue le JSX et insère les nœuds DOM résultants. Les initialiseurs useState s'exécutent, les objets useRef sont créés. Après l'insertion DOM, useLayoutEffect s'exécute de manière synchrone, puis useEffect de manière asynchrone après le dessin.
Lorsque setState ou une nouvelle prop arrive, React met en file d'attente un re-rendu. Pendant le re-rendu, les hooks sont appelés dans le même ordre qu'au montage. React compare la nouvelle et l'ancienne sortie et met à jour le DOM. Avant de ré-exécuter les effets, React exécute les fonctions de nettoyage des effets du rendu précédent.
Avant chaque ré-exécution d'effet (et au démontage), React appelle la fonction de nettoyage de l'effet précédent. C'est crucial pour effacer les timers, annuler les requêtes et se désabonner des événements.
Lorsqu'un composant est retiré (rendu conditionnel, changement de route, etc.), React exécute toutes les fonctions de nettoyage — nettoyage useEffect, puis nettoyage useLayoutEffect. Les nœuds DOM sont retirés du document.
Tableau de deps vide : s'exécute une fois après le montage. Le nettoyage s'exécute au démontage. Équivalent à componentDidMount + componentWillUnmount.
S'exécute après le montage ET chaque fois que dep change. Le nettoyage s'exécute avant chaque ré-exécution et au démontage.
Sans tableau de deps : s'exécute après chaque rendu. Rarement ce que vous souhaitez — cause des boucles infinies s'il déclenche des changements de state.
Même signature que useEffect mais se déclenche de manière synchrone après les mutations DOM, avant le dessin. À utiliser pour les mesures DOM.
La fonction retournée par un callback useEffect. React l'appelle avant la prochaine exécution d'effet et au démontage.
1function Component({ userId }) {2 const [data, setData] = useState(null);34 useEffect(() => {5 // Runs after mount and when userId changes6 let cancelled = false;78 fetch(`/api/user/${userId}`)9 .then(res => res.json())10 .then(json => {11 if (!cancelled) setData(json); // guard against stale closure12 });1314 // Cleanup: cancel if userId changes before fetch resolves15 return () => { cancelled = true; };16 }, [userId]); // re-runs when userId changes1718 // Runs on unmount19 useEffect(() => {20 return () => console.log('Component unmounted');21 }, []);22}
Comprendre le timing du cycle de vie prévient les bugs React les plus courants : récupérer des données sans nettoyage (cause des avertissements setState sur un composant démonté), oublier d'effacer les timers (cause des fuites mémoire) et exécuter les effets trop souvent ou trop rarement en mal utilisant le tableau de dépendances.
A user profile page fetches user data on mount. If a user rapidly clicks through profiles (User A → User B → User C), the displayed data sometimes shows User A's data on User C's page.
Each navigation triggers a re-mount with a new userId. The useEffect fires 3 fetch calls, but they resolve out of order: User B (fast) → User C (fast) → User A (slow). The last-resolving fetch (User A) overwrites the correct data.
Use the cleanup function to set a `cancelled` flag. When userId changes, the previous effect's cleanup runs before the new effect, marking the old fetch as stale. The guard `if (!cancelled) setData(json)` prevents stale responses from updating state.
Takeaway: The cleanup function in useEffect isn't just for unmounting — it runs before EVERY re-execution of the effect. This makes it the perfect place to cancel async operations and prevent race conditions.
A chart component adds a `window.resize` event listener on mount to recalculate dimensions. After navigating away, the browser's memory usage keeps climbing and console shows 'setState on unmounted component' warnings.
The event listener was added in useEffect but never cleaned up. The component unmounts, but the listener still holds a reference to the component's state setter, creating a memory leak and triggering warnings on resize.
Return a cleanup function from useEffect that removes the event listener. The cleanup runs during the Unmount phase, before DOM removal, ensuring no orphaned listeners persist. Apply the same pattern for WebSocket connections, interval timers, and IntersectionObserver instances.
Takeaway: Every subscription, listener, or timer created in useEffect MUST have a corresponding cleanup. Think of mount/unmount as a pair: every 'set up' action needs a corresponding 'tear down' action.