OUJOOD.COM
Introduction
Les composants sont le cœur de React. Ils permettent de découper une interface utilisateur en parties indépendantes et réutilisables. Dans ce chapitre, nous allons explorer :
- Qu'est-ce qu'un composant React ?
- Comment créer des composants fonctionnels et basés sur des classes.
- Des exemples pratiques pour illustrer leur utilisation.
Qu'est-ce qu'un Composant React ?
Un composant React est une fonction ou une classe qui prend des entrées (appelées props
) et retourne un élément React décrivant ce qui doit être affiché à l'écran. Les composants peuvent être imbriqués pour créer des interfaces complexes.
Il existe deux types principaux de composants :
- Composants fonctionnels : Plus simples et modernes, ils utilisent des fonctions JavaScript pour définir l'interface utilisateur.
- Composants basés sur des classes : Utilisés avant l'introduction des hooks, ils permettent de gérer l'état et le cycle de vie des composants.
1. Composants Fonctionnels
Les composants fonctionnels sont le moyen le plus simple et moderne de créer des composants React. Ils sont basés sur des fonctions JavaScript pures et utilisent une syntaxe concise pour définir l'interface utilisateur.
Qu'est-ce qu'un Composant Fonctionnel ?
Un composant fonctionnel est simplement une fonction JavaScript qui retourne du JSX. Il prend des données (appelées props
) comme entrée et génère un élément React à afficher à l'écran.
Voici un exemple simple pour illustrer ce concept :
function Bonjour({ nom }) { return <h1>Bonjour, {nom} !</h1>; } ReactDOM.render(<Bonjour nom="Alice" />, document.getElementById('root'));
Explication ligne par ligne :
-
function Bonjour({ nom }) { ... }
:- Ceci définit une fonction JavaScript appelée
Bonjour
. - Les accolades
{ nom }
représentent la destructuration. Cela signifie que nous extrayons automatiquement la propriéténom
des props passées au composant.
- Ceci définit une fonction JavaScript appelée
-
return <h1>Bonjour, {nom} !</h1>;
:- Cette ligne retourne du JSX, qui est ensuite interprété par React pour afficher un élément
<h1>
contenant le texte "Bonjour, Alice !" sinom
vaut "Alice". {nom}
insère dynamiquement la valeur de la variablenom
dans le JSX.
- Cette ligne retourne du JSX, qui est ensuite interprété par React pour afficher un élément
-
ReactDOM.render(<Bonjour nom="Alice" />, document.getElementById('root'));
:- Cette ligne utilise
ReactDOM.render()
pour insérer le composantBonjour
dans le DOM. <Bonjour nom="Alice" />
: Ici, nous utilisons le composantBonjour
en lui passant une prop appeléenom
avec la valeur "Alice".document.getElementById('root')
: Cette partie indique où dans le DOM le composant doit être rendu. Typiquement, un élément HTML avec l'idroot
est utilisé comme point d'insertion.
- Cette ligne utilise
Pourquoi Utiliser des Composants Fonctionnels ?
Les composants fonctionnels sont privilégiés dans React car ils sont simples, faciles à lire et performants. Voici quelques avantages clés :
- Syntaxe concise : Ils utilisent une syntaxe minimaliste qui facilite leur compréhension.
- Support des Hooks : Avec l'introduction des hooks (comme
useState
ouuseEffect
), les composants fonctionnels peuvent désormais gérer l'état et le cycle de vie sans avoir besoin de classes. - Rapidité de développement : Ils permettent d'écrire moins de code tout en restant puissants.
Exemple Étendu : Création d'un Composant Fonctionnel Réutilisable
Imaginons que vous souhaitiez créer un composant qui salue une personne en affichant son prénom et sa ville. Voici comment cela peut être fait :
function Saluer({ nom, ville }) { return ( <div> <h1>Bonjour, {nom} !</h1> <p>Vous habitez à {ville}.</p> </div> ); } // Utilisation du composant ReactDOM.render( <Saluer nom="Alice" ville="Paris" />, document.getElementById('root') );
Explication détaillée :
-
function Saluer({ nom, ville }) { ... }
:- Nous créons une fonction appelée
Saluer
. - Avec
{ nom, ville }
, nous utilisons la destructuration pour extraire directement les propriétésnom
etville
des props passées au composant.
- Nous créons une fonction appelée
-
return ( ... );
:- La fonction retourne une structure JSX contenant deux éléments : un
<h1>
et un<p>
. {nom}
et{ville}
insèrent dynamiquement les valeurs des props correspondantes dans le JSX.
- La fonction retourne une structure JSX contenant deux éléments : un
-
ReactDOM.render( ... )
:- Cette méthode rend le composant
Saluer
dans l'élément HTML ayant l'idroot
. <Saluer nom="Alice" ville="Paris" />
: Nous passons deux props (nom
etville
) avec leurs valeurs respectives.
- Cette méthode rend le composant
Comment Passer des Props à un Composant Fonctionnel ?
Les props sont des données transmises d'un composant parent à un composant enfant. Elles permettent de rendre le composant réutilisable en acceptant différentes valeurs selon l'utilisation.
Voici un exemple où le même composant est utilisé plusieurs fois avec des props différentes :
function Saluer({ nom, ville }) { return ( <div> <h1>Bonjour, {nom} !</h1> <p>Vous habitez à {ville}.</p> </div> ); } function App() { return ( <div> <Saluer nom="Alice" ville="Paris" /> <Saluer nom="Bob" ville="Lyon" /> <Saluer nom="Charlie" ville="Marseille" /> </div> ); } ReactDOM.render(<App />, document.getElementById('root'));
Explication détaillée :
-
function App() { ... }
:- Nous créons un composant parent appelé
App
. - Ce composant utilise trois instances du composant
Saluer
, chacune avec des props différentes.
- Nous créons un composant parent appelé
-
<Saluer nom="Alice" ville="Paris" />
:- Ici, nous utilisons le composant
Saluer
avec les propsnom="Alice"
etville="Paris"
. - Cela affichera :
<h1>Bonjour, Alice !</h1> <p>Vous habitez à Paris.</p>
- Ici, nous utilisons le composant
-
ReactDOM.render(<App />, document.getElementById('root'));
:- Cette ligne rend le composant
App
dans l'élément HTML ayant l'idroot
. - Le composant
App
inclut trois instances du composantSaluer
, chacune avec ses propres props.
- Cette ligne rend le composant
Composants Fonctionnels avec État (Hooks)
Bien que les composants fonctionnels soient initialement statiques, ils peuvent désormais gérer l'état grâce aux hooks (introduits dans React 16.8). Le hook useState
est particulièrement utile pour ajouter un état local à un composant fonctionnel.
Voici un exemple de compteur utilisant useState
:
import React, { useState } from 'react'; function Compteur() { // Initialisation de l'état "compte" avec la valeur 0 const [compte, setCompte] = useState(0); // Fonction pour incrémenter le compteur function incrementer() { setCompte(compte + 1); } return ( <div> <p>Vous avez cliqué {compte} fois.</p> <button onClick={incrementer}> Cliquez ici </button> </div> ); } ReactDOM.render(<Compteur />, document.getElementById('root'));
Explication détaillée :
-
import React, { useState } from 'react';
:- Nous importons React et le hook
useState
depuis la bibliothèque React.
- Nous importons React et le hook
-
const [compte, setCompte] = useState(0);
:useState
est un hook qui permet d'ajouter un état local à un composant fonctionnel.compte
représente la valeur actuelle de l'état.setCompte
est une fonction qui met à jour cette valeur.- Ici, nous initialisons
compte
à 0.
-
function incrementer() { setCompte(compte + 1); }
:- Cette fonction incrémente la valeur de
compte
lorsque le bouton est cliqué. setCompte(compte + 1)
met à jour l'état en ajoutant 1 à la valeur actuelle decompte
.
- Cette fonction incrémente la valeur de
-
onClick={incrementer}
:- Cet attribut lie la fonction
incrementer
à l'événement de clic du bouton. - Lorsque le bouton est cliqué,
incrementer
est exécutée, mettant à jour l'état.
- Cet attribut lie la fonction
Conclusion
Les composants fonctionnels sont une méthode simple et efficace pour créer des interfaces utilisateur dans React. Grâce aux hooks comme useState
, ils peuvent également gérer l'état et devenir encore plus puissants. Maintenant que vous comprenez comment ils fonctionnent, vous pouvez commencer à créer vos propres composants réutilisables.
2. Composants Basés sur des Classes
Avant l'introduction des hooks dans React 16.8, les composants basés sur des classes étaient la méthode principale pour créer des composants qui gèrent un état ou interagissent avec le cycle de vie de React. Bien que les composants fonctionnels soient maintenant privilégiés, il est important de comprendre comment fonctionnent les composants basés sur des classes, car ils sont encore largement utilisés dans de nombreux projets existants.
Qu'est-ce qu'un Composant Basé sur une Classe ?
Un composant basé sur une classe est une classe JavaScript qui hérite de React.Component
. Il possède plusieurs caractéristiques distinctives :
- État local : Les composants basés sur des classes peuvent avoir leur propre état grâce à la propriété
this.state
. - Cycle de vie : Ils permettent d'utiliser des méthodes spéciales appelées "méthodes de cycle de vie" (par exemple,
componentDidMount
,componentDidUpdate
, etc.). - Contexte (
this
) explicite : Contrairement aux composants fonctionnels, vous devez souvent lier explicitement les fonctions au contextethis
.
Exemple Simple : Création d'un Composant Basé sur une Classe
Voici un exemple simple d'un composant basé sur une classe qui affiche un message personnalisé :
class Bonjour extends React.Component { render() { return <h1>Bonjour, {this.props.nom} !</h1>; } } ReactDOM.render(<Bonjour nom="Alice" />, document.getElementById('root'));
Explication ligne par ligne :
-
class Bonjour extends React.Component { ... }
:- Cette ligne définit une classe JavaScript appelée
Bonjour
qui hérite deReact.Component
. Tous les composants basés sur des classes doivent étendre cette classe de base.
- Cette ligne définit une classe JavaScript appelée
-
render() { ... }
:- Toute classe React doit inclure une méthode
render()
. Cette méthode retourne ce que le composant doit afficher à l'écran sous forme de JSX.
- Toute classe React doit inclure une méthode
-
return <h1>Bonjour, {this.props.nom} !</h1>;
:- Cette ligne retourne du JSX contenant un élément
<h1>
. {this.props.nom}
insère dynamiquement la valeur de la propnom
passée au composant.
- Cette ligne retourne du JSX contenant un élément
-
ReactDOM.render(<Bonjour nom="Alice" />, document.getElementById('root'));
:- Cette ligne rend le composant
Bonjour
dans l'élément HTML ayant l'idroot
. <Bonjour nom="Alice" />
passe la valeur "Alice" comme propnom
au composant.
- Cette ligne rend le composant
Composants Basés sur des Classes avec État
Les composants basés sur des classes peuvent également gérer leur propre état via la propriété this.state
. Voici un exemple d'un compteur utilisant un composant basé sur une classe :
class Compteur extends React.Component { constructor(props) { super(props); this.state = { compte: 0 }; // Initialisation de l'état } handleClick = () => { this.setState({ compte: this.state.compte + 1 }); // Mise à jour de l'état }; render() { return ( <div> <p>Vous avez cliqué {this.state.compte} fois.</p> <button onClick={this.handleClick}> Cliquez ici </button> </div> ); } } ReactDOM.render(<Compteur />, document.getElementById('root'));
Explication détaillée :
-
class Compteur extends React.Component { ... }
:- Nous créons une classe appelée
Compteur
qui hérite deReact.Component
.
- Nous créons une classe appelée
-
constructor(props) { ... }
:- Le constructeur est une méthode spéciale appelée lorsqu'une instance de la classe est créée.
super(props)
: Appel obligatoire pour initialiser correctement la classe parenteReact.Component
.this.state = { compte: 0 };
: Initialise l'état local du composant avec une propriétécompte
définie à 0.
-
handleClick = () => { ... }
:- Cette ligne définit une fonction fléchée appelée
handleClick
. - Elle utilise
this.setState()
pour mettre à jour l'état du composant. this.setState({ compte: this.state.compte + 1 })
incrémente la valeur decompte
de 1.
- Cette ligne définit une fonction fléchée appelée
-
render() { ... }
:- Cette méthode est obligatoire dans tous les composants basés sur des classes.
- Elle retourne une structure JSX qui décrit ce que le composant doit afficher.
-
<p>Vous avez cliqué {this.state.compte} fois.</p>
:- Affiche le nombre actuel de clics stocké dans l'état
this.state.compte
.
- Affiche le nombre actuel de clics stocké dans l'état
-
<button onClick={this.handleClick}>Cliquez ici</button>
:- Ce bouton appelle la fonction
handleClick
lorsque l'utilisateur clique dessus. onClick={this.handleClick}
lie l'événement de clic du bouton à la fonctionhandleClick
.
- Ce bouton appelle la fonction
Pourquoi Utiliser des Composants Basés sur des Classes ?
Les composants basés sur des classes offrent plusieurs avantages, notamment :
- Gestion de l'état : Ils permettent de gérer facilement l'état local via
this.state
. - Méthodes de cycle de vie : Vous pouvez utiliser des méthodes comme
componentDidMount
,componentDidUpdate
, etc., pour exécuter du code à des moments précis du cycle de vie du composant. - Compatibilité rétroactive : Beaucoup de projets React existants utilisent encore des composants basés sur des classes, donc il est important de les connaître même si les composants fonctionnels sont maintenant recommandés.
Exemple Étendu : Gestion de l'État et des Événements
Imaginons que vous souhaitiez créer un composant qui permet à l'utilisateur de changer son prénom en cliquant sur un bouton. Voici comment cela peut être fait :
class Saluer extends React.Component { constructor(props) { super(props); this.state = { nom: "Utilisateur" }; // Initialisation de l'état } handleChangeNom(nouveauNom) { this.setState({ nom: nouveauNom }); // Met à jour l'état } render() { return ( <div> <h1>Bonjour, {this.state.nom} !</h1> <button onClick={() => this.handleChangeNom("Alice")}> Devenir Alice </button> <button onClick={() => this.handleChangeNom("Bob")}> Devenir Bob </button> </div> ); } } ReactDOM.render(<Saluer />, document.getElementById('root'));
Explication détaillée :
-
class Saluer extends React.Component { ... }
:- Nous créons une classe appelée
Saluer
qui hérite deReact.Component
.
- Nous créons une classe appelée
-
constructor(props) { ... }
:- Le constructeur initialise l'état du composant avec une propriété
nom
définie à "Utilisateur". super(props)
est nécessaire pour initialiser correctement la classe parente.
- Le constructeur initialise l'état du composant avec une propriété
-
handleChangeNom(nouveauNom) { ... }
:- Cette méthode met à jour la propriété
nom
de l'état avec une nouvelle valeur. this.setState({ nom: nouveauNom })
met à jour l'état de manière asynchrone.
- Cette méthode met à jour la propriété
-
render() { ... }
:- Cette méthode retourne une structure JSX contenant un titre
<h1>
et deux boutons. {this.state.nom}
insère dynamiquement la valeur de l'étatnom
dans le JSX.
- Cette méthode retourne une structure JSX contenant un titre
-
<button onClick={() => this.handleChangeNom("Alice")}>Devenir Alice</button>
:- Lorsque cet événement de clic est déclenché, la méthode
handleChangeNom
est appelée avec la valeur "Alice". - Cela met à jour l'état
nom
et force React à re-render le composant avec le nouveau nom.
- Lorsque cet événement de clic est déclenché, la méthode
Composants Basés sur des Classes avec Méthodes de Cycle de Vie
Les composants basés sur des classes peuvent également utiliser des méthodes de cycle de vie pour exécuter du code à des moments spécifiques de leur existence. Voici un exemple utilisant componentDidMount
:
class Horloge extends React.Component { constructor(props) { super(props); this.state = { date: new Date() }; // Initialisation de l'état avec la date actuelle } componentDidMount() { this.timerID = setInterval(() => { this.setState({ date: new Date() }); // Met à jour l'état toutes les secondes }, 1000); } componentWillUnmount() { clearInterval(this.timerID); // Nettoie l'intervalle lorsque le composant est démonté } render() { return ( <div> <h1>Heure actuelle :</h1> <h2>{this.state.date.toLocaleTimeString()}</h2> </div> ); } } ReactDOM.render(<Horloge />, document.getElementById('root'));
Explication détaillée :
-
constructor(props) { ... }
:- Initialise l'état avec la date actuelle.
-
componentDidMount() { ... }
:- Cette méthode est appelée après que le composant a été monté (ajouté au DOM).
setInterval(...)
crée un intervalle qui met à jour l'état toutes les secondes.
-
componentWillUnmount() { ... }
:- Cette méthode est appelée juste avant que le composant soit démonté (retiré du DOM).
clearInterval(this.timerID)
arrête l'intervalle pour éviter des fuites mémoire.
-
render() { ... }
:- Retourne une structure JSX contenant l'heure actuelle extraite de l'état.
{this.state.date.toLocaleTimeString()}
affiche l'heure mise à jour en temps réel.
Différences entre Composants Fonctionnels et Basés sur des Classes
Voici quelques différences clés entre les deux types de composants :
Aspect | Composants Fonctionnels | Composants Basés sur des Classes |
---|---|---|
Syntaxe | Plus concise et moderne | Plus verbeuse et complexe |
État | Utilise useState (hook) |
Utilise this.state |
Cycle de vie | Utilise des hooks comme useEffect |
Utilise des méthodes comme componentDidMount et componentWillUnmount |
Maintenance | Plus facile à maintenir grâce à leur simplicité | Peut être plus difficile à maintenir en raison de leur complexité |
Conclusion
Les composants basés sur des classes sont une méthode puissante pour créer des composants React, surtout lorsqu'il s'agit de gérer l'état ou d'utiliser des méthodes de cycle de vie. Bien que les composants fonctionnels avec hooks soient désormais privilégiés pour leur simplicité, comprendre les composants basés sur des classes est essentiel pour travailler sur des projets existants ou avancés.
3. Composants Réutilisables
Les composants React sont conçus pour être réutilisables. Voici un exemple où un composant est utilisé plusieurs fois avec des props différentes :
function Saluer({ message, nom }) { return <p>{message}, {nom} !</p>; } function App() { return ( <div> <Saluer message="Bonjour" nom="Alice" /> <Saluer message="Salut" nom="Bob" /> </div> ); } ReactDOM.render(<App />, document.getElementById('root'));
Explication :
function Saluer({ message, nom })
: Définit un composant fonctionnel qui accepte deux props :message
etnom
.<Saluer message="Bonjour" nom="Alice" />
: Utilise le composantSaluer
avec des valeurs spécifiques pour les props.function App()
: Composant parent qui utilise plusieurs instances du composantSaluer
.
4. Composants avec État
Les composants peuvent également gérer leur propre état. Voici un exemple utilisant useState
pour créer un compteur :
import React, { useState } from 'react'; function Compteur() { const [compte, setCompte] = useState(0); return ( <div> <p>Vous avez cliqué {compte} fois.</p> <button onClick={() => setCompte(compte + 1)}> Cliquez ici </button> </div> ); } ReactDOM.render(<Compteur />, document.getElementById('root'));
Explication :
const [compte, setCompte] = useState(0)
: Initialise l'étatcompte
avec la valeur0
.setCompte(compte + 1)
: Met à jour l'état lorsque le bouton est cliqué.
5. Meilleures Pratiques pour les Composants
Pour écrire des composants React efficaces et maintenables, voici quelques conseils :
- Gardez les composants petits et modulaires : Divisez votre interface en petits composants réutilisables.
- Nommez vos composants explicitement : Utilisez des noms descriptifs pour rendre votre code plus lisible.
- Privilégiez les composants fonctionnels : Ils sont plus simples et performants grâce aux hooks.
Conclusion
Vous avez maintenant appris à créer et utiliser des composants React, qu'ils soient fonctionnels ou basés sur des classes. En combinant des composants réutilisables, vous pouvez construire des interfaces utilisateur complexes et modulaires.
Prochain chapitre : Composants Basés sur des Classes