ReactJS - Cycle de vie des composants

Bonjour à tous, futurs développeurs React ! Aujourd'hui, nous allons entreprendre un voyage passionnant à travers le cycle de vie des composants React. Ne vous inquiétez pas si vous êtes nouveaux dans la programmation - je serai votre guide amical, expliquant tout pas à pas. À la fin de ce tutoriel, vous aurez une compréhension solide de la manière dont les composants React naissent, grandissent et, enfin, disparaissent. C'est parti !

ReactJS - Component Life Cycle

Qu'est-ce qu'un cycle de vie ?

Avant de plonger dans le code, parlons de ce que nous entendons par "cycle de vie". Comme nous, les humains, passons par différentes étapes de la vie (naissance, croissance et, eh bien, vous savez...), les composants React ont également leurs propres étapes de vie. Ces étapes sont appelées le cycle de vie du composant.

Pensez à un composant React comme un animal de compagnie virtuel. Lorsque vous le créez pour la première fois, il naît. Ensuite, il grandit et change à mesure que vous interagissez avec lui. Enfin, lorsque vous n'en avez plus besoin, il disparaît. Comprendre ce cycle de vie est crucial pour créer des applications React dynamiques et efficaces.

Les trois principales phases d'un composant

Les composants React passent par trois principales phases :

  1. Montage (Naissance)
  2. Mise à jour (Croissance)
  3. Démontage (Adieu)

Explorons chacune de ces phases et les méthodes associées.

1. Phase de montage

C'est lorsque notre composant naît et est ajouté au DOM (Document Object Model - imaginez-le comme l'arbre familial de votre page web).

Méthodes clés dans cette phase :

Méthode Description
constructor() Le constructeur du composant, appelé avant qu'il ne soit monté
render() La méthode qui rend réellement le composant
componentDidMount() Appelé après que le composant a été monté dans le DOM

Voici un exemple simple :

import React, { Component } from 'react';

class BabyComponent extends Component {
constructor(props) {
super(props);
this.state = { message: "Je viens de naître !" };
console.log("Constructeur : Salut, je suis en train d'être créé !");
}

componentDidMount() {
console.log("componentDidMount : Je suis maintenant dans le DOM !");
}

render() {
console.log("Render : Je suis en train d'être rendu !");
return <h1>{this.state.message}</h1>;
}
}

export default BabyComponent;

Dans cet exemple, notre BabyComponent traverse sa phase de naissance. Le constructor est appelé en premier, initialisant l'état. Ensuite, render est appelé pour créer les éléments DOM réels. Enfin, componentDidMount est appelé, indiquant que notre composant est maintenant pleinement né et ajouté au DOM.

2. Phase de mise à jour

Cette phase se produit lorsque l'état d'un composant change ou qu'il reçoit de nouvelles props.

Méthodes clés dans cette phase :

Méthode Description
shouldComponentUpdate() Détermine si le composant doit se re-render
render() Re-render le composant avec les données mises à jour
componentDidUpdate() Appelé après que le composant a été mis à jour

Reprenons notre exemple précédent :

import React, { Component } from 'react';

class GrowingComponent extends Component {
constructor(props) {
super(props);
this.state = { age: 0 };
}

componentDidMount() {
this.ageInterval = setInterval(() => {
this.setState(prevState => ({ age: prevState.age + 1 }));
}, 1000);
}

shouldComponentUpdate(nextProps, nextState) {
return nextState.age % 5 === 0; // Seulement mettre à jour tous les 5 ans
}

componentDidUpdate() {
console.log(`Je viens d'avoir ${this.state.age} ans !`);
}

render() {
return <h1>J'ai {this.state.age} ans</h1>;
}

componentWillUnmount() {
clearInterval(this.ageInterval);
}
}

export default GrowingComponent;

Dans cet exemple, notre GrowingComponent "vieillit" chaque seconde. La méthode shouldComponentUpdate nous assure que nous ne fêtons les anniversaires que tous les 5 ans (pour économiser sur le gâteau, vous savez). Lorsque le composant est mis à jour, componentDidUpdate affiche un message d'anniversaire.

3. Phase de démontage

C'est la phase d'adieu, lorsque le composant est supprimé du DOM.

Méthode clé dans cette phase :

Méthode Description
componentWillUnmount() Appelé juste avant que le composant soit démonté et détruit

Dans notre exemple GrowingComponent ci-dessus, nous avons utilisé componentWillUnmount pour effacer l'intervalle que nous avions configuré, évitant ainsi les fuites mémoires.

Exemple complet de l'API de cycle de vie

Maintenant, mettons tout cela ensemble dans un exemple plus complexe. Nous allons créer une application simple "Suiveur de mood" qui montre tous les méthodes de cycle de vie.

import React, { Component } from 'react';

class MoodTracker extends Component {
constructor(props) {
super(props);
this.state = { mood: 'neutre', intensity: 5 };
console.log('Constructeur : Le Suiveur de mood est en train d\'être créé');
}

componentDidMount() {
console.log('ComponentDidMount : Le Suiveur de mood est maintenant dans le DOM');
this.moodInterval = setInterval(() => {
const moods = ['heureux', 'triste', 'excité', 'nerveux', 'neutre'];
const newMood = moods[Math.floor(Math.random() * moods.length)];
this.setState({ mood: newMood });
}, 5000);
}

shouldComponentUpdate(nextProps, nextState) {
return this.state.mood !== nextState.mood;
}

componentDidUpdate() {
console.log(`Mood mis à jour : ${this.state.mood}`);
}

componentWillUnmount() {
console.log('ComponentWillUnmount : Au revoir Suiveur de mood !');
clearInterval(this.moodInterval);
}

handleIntensityChange = (e) => {
this.setState({ intensity: e.target.value });
}

render() {
console.log('Render : Le Suiveur de mood est en train de se rendre');
return (
<div>
<h1>Mood actuel : {this.state.mood}</h1>
<input
type="range"
min="1"
max="10"
value={this.state.intensity}
onChange={this.handleIntensityChange}
/>
<p>Intensité : {this.state.intensity}</p>
</div>
);
}
}

export default MoodTracker;

Ce composant MoodTracker montre toutes les méthodes de cycle de vie que nous avons discutées. Il change de mood aléatoirement toutes les 5 secondes et permet à l'utilisateur de régler l'intensité du mood.

API de cycle de vie dans une application Gestionnaire de dépenses

Maintenant, voyons comment nous pourrions utiliser ces méthodes de cycle de vie dans une application pratique comme un Gestionnaire de dépenses.

import React, { Component } from 'react';

class ExpenseManager extends Component {
constructor(props) {
super(props);
this.state = { expenses: [], total: 0 };
}

componentDidMount() {
// Simuler la récupération des dépenses d'une API
setTimeout(() => {
const fetchedExpenses = [
{ id: 1, description: 'Courses', amount: 50 },
{ id: 2, description: 'Carburant', amount: 30 },
{ id: 3, description: 'Billets de cinéma', amount: 20 },
];
this.setState({ expenses: fetchedExpenses }, this.calculateTotal);
}, 1000);
}

shouldComponentUpdate(nextProps, nextState) {
// Mettre à jour uniquement si le total a changé
return this.state.total !== nextState.total;
}

componentDidUpdate() {
console.log(`Total des dépenses mis à jour : $${this.state.total}`);
}

calculateTotal = () => {
const total = this.state.expenses.reduce((sum, expense) => sum + expense.amount, 0);
this.setState({ total });
}

render() {
return (
<div>
<h1>Gestionnaire de dépenses</h1>
<ul>
{this.state.expenses.map(expense => (
<li key={expense.id}>{expense.description} : ${expense.amount}</li>
))}
</ul>
<h2>Total : ${this.state.total}</h2>
</div>
);
}
}

export default ExpenseManager;

Dans ce composant ExpenseManager :

  1. Nous utilisons componentDidMount pour simuler la récupération des données de dépenses d'une API lorsque le composant est chargé pour la première fois.
  2. shouldComponentUpdate nous assure que nous ne re-render que lorsque le total change, pas pour chaque petite mise à jour.
  3. componentDidUpdate affiche le nouveau total chaque fois qu'il change.

En utilisant ces méthodes de cycle de vie, nous créons une application de suivi des dépenses plus efficace et réactive.

Comprendre le cycle de vie des composants est crucial pour construire des applications React efficaces. Il vous permet de contrôler lorsque certaines actions se produisent, d'optimiser les performances et de gérer les ressources efficacement. Continuez à pratiquer avec ces concepts, et bientôt vous serez en mesure de créer des applications React complexes et dynamiques avec facilité !

Credits: Image by storyset