React Class Components 03.2 - Life Cycle Deepening
Introduction
Dans les quêtes précédentes, tu as découvert componentDidMount, l'une des méthodes de cycle de vie les plus utilisées.
L'un de ses cas d'usage est le lancement de requêtes API quand un composant est ajouté pour la première fois à une page. Mais le lifecycle (cycle de vie du composant) va bien plus loin !
C'est parti ! 🚀
🤓 À la fin de ce cours, tu seras capable de :
✅ Avoir une vue d'ensemble du cycle de vie d'un composant.
✅ Comprendre componentWillUnmount.
✅ Comprendre componentDidUpdate.
✅ Utiliser componentDidUpdate avec React Router.
Vue d'ensemble
Mosh Hamedani compare les méthodes de cycle de vie à "des événements qui se produisent depuis la naissance d'un composant React jusqu'à sa mort".
En suivant cette métaphore :
componentDidMountest appelée juste après la "naissance" d'un composant,componentDidUpdatefournit une réponse à toute mise à jour desprops/statedu composant, pendant sa durée de vie,componentWillUnmountest la méthode "symétrique" decomponentDidMount. Elle te permet d'exécuter du code juste avant qu'un composant ne soit retiré du DOM, c'est-à-dire avant qu'il ne "meure".
Dans cette quête, tu vas en apprendre plus sur ces deux dernières méthodes, qui peuvent servir à résoudre les problèmes les plus courants.
Cette quête s'appuie sur des ressources (documentation officielle, articles de blog) que tu dois lire attentivement. L'idée est de t'habituer à lire de la documentation en anglais. Si cet exercice te paraît difficile au début, n'hésite pas à travailler avec un ou une camarade sur la section
componentDidUpdate.
Cette application interactive te montre les principales étapes du cycle de vie :
- Le montage (Mounting, la naissance)
- La mise à jour (Update, la croissance)
- Le démontage (Dismantling, la mort)
Ce qu'il est important de comprendre dans ce diagramme, c'est ceci :
- Il existe de nombreuses méthodes de cycle de vie au-delà de
componentDidMount,componentDidUpdateetcomponentWillUnmount. Cependant, connaître ces trois-là devrait suffire à couvrir la plupart des cas d'usage. - Mettre à jour les props d'un composant (depuis son composant parent) ou appeler
setStatedéclenchera un nouvel appel àrender, suivi de la méthodecomponentDidUpdate.
Important : Si tu cherches "react lifecycle" sur internet, tu as de grandes chances de tomber sur des ressources qui mentionnent les méthodes
componentWillMount,componentWillUpdateetcomponentWillReceiveProps. Ces méthodes sont désormais deprecated (dépréciées, déconseillées) depuis React 16.3 (mars 2018) : en cas de doute, essaie de toujours te référer à la documentation officielle.
Dépôt GitHub
Version en ligne
Symétrie entre le montage et le démontage
componentDidMount te permet d'initialiser des choses juste après le premier render d'un composant. À l'inverse, componentWillUnmount nous permet de nettoyer toute opération en cours juste avant qu'il ne soit retiré de la page.
Un très bon exemple est donné par la documentation officielle, dans la section Adding Lifecycle Methods to a Class.
Les timers en JavaScript
Les timers (minuteurs) sont vraiment utiles, alors lis bien toute cette section, y compris la documentation DND sur setInterval (sections "Syntax" et "Example"). Note que setInterval est une fonction built-in (native, intégrée au langage) de JavaScript et n'est pas spécifique à React.
Pour te permettre de mieux comprendre, voici un exemple de setInterval sur CodePen.
https://codepen.io/wildcodeschool/pen/QWWqLxe
Au chargement du HTML, la fonction startFlashText est appelée et démarre un timer à l'aide de setInterval. On passe la fonction changeColour à setInterval, qui sera appelée automatiquement toutes les secondes (1000 millisecondes) comme indiqué dans le 2e argument de setInterval. Cette fonction va faire basculer la couleur du texte du rouge au bleu.
La valeur de retour de setInterval est stockée dans intervalID. Elle identifie le timer, afin de pouvoir l'arrêter plus tard quand il n'est plus nécessaire. Appuyer sur le bouton "Stop" déclenche l'appel de stopFlashText qui arrête le timer en effaçant l'intervalle avec clearInterval, auquel on passe l'intervalID.
Utilisation avec React
Comme expliqué dans cette quête, une fois que l'horloge Clock est initialisée avec une date initiale dans le state, on peut alors démarrer un timer à l'intérieur de componentDidMount, qui sera arrêté à l'intérieur de componentWillUnmount.
Ce timer mettra à jour la date du state à intervalles réguliers. Arrêter le timer quand le composant est retiré de la page libère des ressources et est une bonne pratique (pourquoi mettre à jour quelque chose qui n'est plus affiché ?).
Malheureusement, l'exemple de la documentation ne montre pas précisément ce qui se passe quand le composant Clock est retiré de la page.
Cet exemple légèrement différent va te permettre de mieux visualiser l'ordre dans lequel les méthodes de cycle de vie sont appelées.
https://codepen.io/wildcodeschool/pen/OJJxJWL?editors=0010
Le composant Clock est un enfant d'App, et App contient une valeur booléenne showClock qui indique si Clock doit être affiché ou non.
Voyons ce qui apparaît dans la console du navigateur quand tu appuies sur le bouton "Show clock", puis une autre fois après avoir caché l'horloge quelques secondes plus tard.
Un autre cas d'usage de
componentDidMountetcomponentWillUnmountpourrait être l'écoute d'événements spécifiques en utilisantaddEventListenerdanscomponentDidMountetremoveEventListenerdanscomponentWillUnmount.
Mises à jour des props et du state
Cette étape porte sur componentDidUpdate et va faire ressurgir quelques souvenirs de componentDidMount et de React Router !
Prenons l'exemple d'un blog. Avec React Router, tu peux déclarer une route dont le composant affiche le contenu complet d'un article. L'identifiant de l'article peut être passé via un paramètre d'URL.
Quand tu affiches le composant pour la première fois, tu peux charger les données de l'article avec axios/fetch dans componentDidMount et mettre à jour le state en conséquence. Mais que se passe-t-il si l'utilisateur clique sur un lien vers un autre article ? Il sera toujours sur la même route mais avec un paramètre d'URL différent (par exemple en passant de /article/1 à /article/2). La page ne sera pas mise à jour, si tu ne récupères pas les données de cet autre article depuis componentDidUpdate.
Ce problème et la façon de le résoudre sont bien décrits dans cet article : A Practical Use Case for React's componentDidUpdate.
Tu n'as pas forcément besoin de recopier les exemples de code, car l'auteur nous a donné des liens CodeSandbox à consulter :
- Un premier montrant l'application de blog dans son état initial, avec le problème de mise à jour.
https://codesandbox.io/s/r1ywq3kkmn
- Un autre montrant la solution au problème.
See solution!|||codesandbox||||||0|||Close solution
https://codesandbox.io/s/x729mr1qjw
Quelques notes pour guider ta lecture :
-
Prends le temps de regarder le code des composants :
App,HomeetPostDetails. -
Dans
Home, une liste deLinkest générée à partir d'une liste d'éléments (posts), qui sont écrits dans un fichier séparé. ChaqueLinkcontient l'idd'un article comme paramètre d'URL. -
Dans
PostDetails, on récupère l'iddepuis l'URL pour ensuite charger l'article demandé. Pour cela, on utilisefetchpostDataavec cetiddanscomponentDidMount). -
Toujours dans
PostDetails,fetchPostData"simule" le chargement d'un article. Au lieu d'interroger un article avec Fetch ou Axios, on récupère un article depuis la listepostsprécédente. Cela se fait avec la méthode Array.find(...) qui fonctionne de la même manière queArray.filter: une fonction est passée en paramètre pour déterminer si un élément répond à un certain critère. Contrairement àfilterqui garde tous les éléments correspondant au critère,findne renvoie que le premier élément correspondant (ouundefineds'il n'y a pas de correspondance). -
Toujours dans
PostDetails, la solution au problème de rechargement des données est fournie à l'aide de componentDidUpdate. La méthode de cycle de viecomponentDidUpdatereçoit les props précédentes comme premier argument. L'idée est de récupérer la valeur actuelle dethis.props.postIdet de la comparer à l'ancienne valeur deprevProps.postId. Si elles sont différentes, on doit appelerfetchPostDatapour charger le nouvel article.
💪 Challenge
Utiliser axios depuis componentDidUpdate
Ce challenge fait suite à l'article sur componentDidUpdate, en simulant un appel API avec fetchPostData.
On te donne maintenant une application dont la structure est très similaire. Ouvre ce CodeSandbox et forke-le (fork, crée ta propre copie modifiable du projet).
Quelques indications sur la structure :
- Il y a deux routes dans
App- Une menant à la page d'accueil qui affiche le composant
Home, lequel affiche une liste de personnages depuisCharacterList. - Une autre affichant les détails d'un personnage via le composant
CharacterDetails.
- Une menant à la page d'accueil qui affiche le composant
- Dans son état initial,
CharacterDetailsne charge aucune donnée. - Ton objectif est de faire en sorte que
CharacterDetailscharge correctement les données :- Ajoute le code manquant (requête API avec
axios) dansloadCharacterDetailspour charger les détails du personnage (l'urlt'est déjà fournie), et mets à jour les données du state (character) en conséquence avec les données reçues. - En t'appuyant sur ce qui est montré dans l'article de la quête, ajoute du code pour détecter le changement de paramètre d'URL. Chaque fois que
characterIdchange, tu lanceras une nouvelle requête pour charger les données de ce personnage (correspondant à la nouvelle valeur decharacterIddans l'URL).
- Ajoute le code manquant (requête API avec
Poste l'URL de ton fork CodeSandbox comme solution.
🧐 Critères de validation
- [ ] Les données d'un personnage sont chargées automatiquement quand tu cliques sur un lien depuis la page d'accueil.
- [ ] Les données sont rechargées quand tu cliques sur un lien vers un autre personnage depuis la page de détails.
Introduction
In the previous quests, you were introduced to componentDidMount, one of the most widely used lifecycle methods.
One of its use cases is the launch of API requests when a component is first added to a page. But there is more to lifecycle!
Let's get it started! 🚀

🤓 By the end of this lecture you will be able to:
✅ Get an overview of a component lifecycle.
✅ Understand componentWillUnmount.
✅ Understand componentDidUpdate.
✅ Use componentDidUpdate with React Router.
Overview
Mosh Hamedani compares lifecycle methods to "events that occur from the birth of a React component until its death".
Following this metaphor:
componentDidMountis called just after the "birth" of a component,componentDidUpdateprovides a response to any componentprops/stateupdates, during the component lifetime,componentWillUnmountthe "symmetrical" ofcomponentDidMount. It allows you to run code just before a component is removed from the DOM, i.e. before it "dies".
In this quest you will find out more about these two last methods, which can be used to solve the most common problems.
This quest is based on resources (official documentation, blog articles) that you should read carefully. The idea is to get used to reading documentation in English. If this exercise proves to be difficult in the beginning, do not hesitate to work with a classmate on the
componentDidUpdatesection.
This interactive application shows you the main stages of the lifecycle:
- Mounting (birth)
- Update (growth)
- Dismantling (death)
What is important to understand from this diagram is the following:
- There are many lifecycle methods beyond
componentDidMount,componentDidUpdateandcomponentWillUnmount. However, knowing these three should be enough to cover most use cases. - Updating a component props (from its parent component) or calling
setStatewill result into a newrendercall, followed by thecomponentDidUpdatemethod.
Important: If you look for "react lifecycle" on the internet, you are likely to find resources mentioning
componentWillMount,componentWillUpdateandcomponentWillReceivePropsmethods. These methods are now deprecated since React 16.3 (March 2018): when in doubt, try to always refer to the official documentation.
Repo GitHub
Online version
Symmetry between Mounting and Unmounting
componentDidMount allows you to initialize things right after a component's first render. On the other hand, componentWillUnmount allows us to clean any ongoing operation just before it is removed from the page.
A very good example is given by the official documentation, in the section Adding Lifecycle Methods to a Class.
Timers in JavaScript
Timers are really useful, so be sure to read this entire section, including the DND documentation on setInterval ("Syntax" and "Example" sections). Note that setInterval is a JavaScript built-in function and is not specific to React.
To make it easier for you to understand, here is a setInterval example on CodePen.
https://codepen.io/wildcodeschool/pen/QWWqLxe
When loading HTML, the startFlashText function is called and starts a timer using setInterval. We pass the function changeColour to setInterval which will be called automatically every second (1000 milliseconds) as mentioned in the 2nd argument of setInterval. This function will toggle the text color from red to blue.
The return value of setInterval is stored in intervalID. It identifies the timer, so that it can be stopped later one when it is no longer needed. Pressing the "Stop" button triggers the call of stopFlashText which stops the timer by clearing the interval using clearInterval to which the intervalID is passed.
Use with React
As explained in this quest, once the Clock is initialized with an initial date in the state, we then can start a timer inside componentDidMount and which will be cleared inside componentWillUnmount.
This timer will update the date from the state at regular intervals. Stopping the timer when the component is removed from the page frees up resources and is good practice (why would you update something that isn't shown anymore?).
Unfortunately, the documentation example does not show precisely what happens when the Clock component is removed from the page.
This slightly different example will allow you to visualize a little better the order in which lifecycle methods are called.
https://codepen.io/wildcodeschool/pen/OJJxJWL?editors=0010
The Clock component is a child of App, and App contains a boolean value showClock which indicates whether or not Clock should be displayed.
Let's see what shows up in the browser console when you press the "Show clock" button, and another time after hiding the clock a few seconds later.
Another use case of
componentDidMountandcomponentWillUnmountcould be for listening to specific events usingaddEventListenerincomponentDidMountandremoveEventListenerincomponentWillUnmount.
Props and State Updates
This step is about componentDidUpdate and will bring back some memories from componentDidMount and React Router!
Let's pick an example of a blog. Using React Router, you can declare a route which component displays the complete content of an article. The article ID can be passed using a URL parameter.
When you show the component for the first time, you can load the material data using axios/fetch in componentDidMount and update the state accordingly. But what happens if the user clicks on a link to another article? They will still be on the same route but with a different URL parameter (e.g. going from /article/1 to /article/2). The page will not be updated, if you don't fetch the data for that other article from componentDidUpdate.
This problem and how to solve it is well described in this article: A Practical Use Case for React's componentDidUpdate.
You don't necessarily need to copy the code samples, because the author gave us CodeSandboxes links to look at:
- A first one showing the blog application in its initial state, with the update problem.
https://codesandbox.io/s/r1ywq3kkmn
- Another one showing the solution to the problem.
See solution!|||codesandbox||||||0|||Close solution
https://codesandbox.io/s/x729mr1qjw
A few notes to guide your reading:
-
Take the time to look at the components code:
App,HomeandPostDetails. -
In
Home, a list ofLinks is generated from a list of items (posts), which are written in a separated file. EachLinkcontains an articleidas a URL parameter . -
In
PostDetails, we get theidfrom the URL to then load the requested article. To do so, they usefetchpostDatawith thatidincomponentDidMount). -
Also in
PostDetailsfetchPostData"simulates" the loading of an article. Instead of querying an article using Fetch or Axios, we get an article from the previouspostslist. This is done using the Array.find(...) method which works in the same way as inArray.filter, a function is passed as a parameter to determine whether an element passes a certain criterion. Unlikefilterwhich keeps all the elements corresponding to the criterion,findonly returns the first matching element (orundefinedif there's no match). -
Still in
PostDetails, the solution to the data reloading problem is provided using componentDidUpdate. ThecomponentDidUpdatelifecycle method takes in the previous props as the first argument. The idea is to get the current value ofthis.props.postIdand compare it to the old value fromprevProps.postId. If they're different, we need to callfetchPostDatato load the new article.
💪 Challenge
Using axios from componentDidUpdate
This challenge follows on from the article about componentDidUpdate, simulating an API call using fetchPostData.
You are now given an application whose structure is very similar. Open this CodeSandbox and fork it.
Some indications about the structure:
- There are two routes in
App- One leading to the homepage showing the
Homecomponent, which displays a list of characters fromCharacterList. - Another one showing a character's details using the
CharacterDetailscomponent.
- One leading to the homepage showing the
- In its initial state,
CharacterDetailsdoes not load any data. - Your goal is to make sure
CharacterDetailsloads the data correctly:- Add missing code (API request using
axios) in theloadCharacterDetailsto load the character's details (theurlis already provided to you), and update the state data (character) accordingly with the data received. - Based on what is shown in the quest article, add code to detect the change of URL parameter. Whenever
characterIdchanges, you will run a new request to load the data for that character (corresponding to the newcharacterIdvalue in the URL).
- Add missing code (API request using
Post the URL of your CodeSandbox fork as a solution.
🧐 Validation criterias
- [ ] A character's data is loaded automatically when you click on a link from the homepage.
- [ ] The data is reloaded when you click on a link to another character from the details page.
Ressources partagées sur cette quête
- Le lien vers setInterval() validehttps://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval
- Adding lifecycle methods to a class component, from the React new official documentation (with another example)https://react.dev/reference/react/Component#adding-lifecycle-methods-to-a-class-component
- componentDidUpdate, from the React new official documentationhttps://react.dev/reference/react/Component#componentdidupdate