Menu

Composants classes React : état, cycle de vie, conversion

Un composant classe est une classe JavaScript qui étend React.Component et renvoie du JSX depuis une méthode render. Découvrez this.props, this.state et setState, la liaison des gestionnaires d'événements, les méthodes de cycle de vie, PureComponent, et comment convertir une classe en composant fonction.

Cette page contient des éditeurs exécutables - modifiez, exécutez et voyez la sortie instantanément.

Un composant classe est une classe JavaScript qui étend React.Component et renvoie du JSX depuis une méthode render(). Il lit les props dans this.props, garde l'état dans this.state et le met à jour avec this.setState(). Les composants fonctions avec hooks les ont remplacés pour le nouveau code, mais les classes restent entièrement prises en charge, apparaissent dans de nombreuses bases de code anciennes, et sont le seul moyen d'écrire une error boundary.

Chaque compteur garde son propre état. Ajoutez un troisième <Counter label="Plums" /> et il démarre lui aussi à 0.

L'anatomie d'un composant classe

import { Component } from 'react';

class Welcome extends Component {
    static defaultProps = { name: 'stranger' };

    constructor(props) {
        super(props); // required before using this
        this.state = { visits: 1 };
    }

    render() {
        return <h1>Hello, {this.props.name}. Visit #{this.state.visits}</h1>;
    }
}
  • La classe étend Component (ou React.Component avec import React from 'react').
  • render() est obligatoire. Elle doit être pure, comme le corps d'un composant fonction : lire this.props et this.state, renvoyer du JSX.
  • this.props contient les props. Elles sont en lecture seule.
  • L'état peut être défini dans un constructor (appelez d'abord super(props)) ou, plus couramment aujourd'hui, comme champ de classe : state = { visits: 1 };.
  • static defaultProps fonctionne toujours pour les classes dans React 19 (il n'a été supprimé que pour les composants fonctions).

this.setState fusionne, et peut prendre une fonction de mise à jour

setState fait deux choses différemment du setter de useState. Il fusionne l'objet que vous passez dans l'état actuel, vous ne mettez donc à jour que les clés que vous nommez. Et, comme toute mise à jour d'état React, il n'est pas appliqué immédiatement : utilisez donc la forme fonction de mise à jour quand la valeur suivante dépend de la précédente.

"+3 with objects" ajoute un, car les trois appels lisent le même this.state.likes. "+3 with updaters" ajoute trois. "Move to Paris" garde name et likes (la fusion) mais perd zip, car la fusion ne va qu'à un niveau de profondeur. Écrivez address: { ...this.state.address, city: 'Paris' } pour le garder. Le second argument facultatif de setState s'exécute après la mise à jour, et la console y affiche la nouvelle adresse.

Lier les gestionnaires d'événements

Une méthode passée sous la forme onClick={this.handleClick} est appelée plus tard comme une simple fonction, sans son objet, donc this y vaut undefined.

Le premier bouton affiche une TypeError à propos de la lecture de setState sur undefined. Le second fonctionne, car une fonction fléchée dans un champ de classe capture this à la création de l'instance. L'ancienne solution, encore courante dans le code legacy, fait la liaison dans le constructeur :

constructor(props) {
    super(props);
    this.state = { on: false };
    this.handleClick = this.handleClick.bind(this);
}

Une fonction fléchée inline, onClick={() => this.handleClick()}, fonctionne aussi.

Méthodes de cycle de vie

Les classes réagissent au montage, à la mise à jour et au démontage par des méthodes aux noms fixes. Celles que vous verrez le plus :

  • componentDidMount() : après l'insertion du premier rendu dans le DOM. Démarrez les minuteurs, les abonnements, les requêtes.
  • componentDidUpdate(prevProps, prevState) : après chaque mise à jour. Comparez avec les valeurs précédentes avant de faire un travail, sinon vous bouclerez.
  • componentWillUnmount() : avant le retrait. Défaites ce que componentDidMount a démarré.
  • shouldComponentUpdate(nextProps, nextState) : renvoyez false pour sauter un rendu.

La page sur le cycle de vie des composants donne la liste complète, l'ordre d'exécution et un composant qui affiche chacune d'elles.

Convertir une classe en composant fonction

Voici une classe qui utilise les trois méthodes de cycle de vie courantes. Elle avance chaque seconde, écrit dans la console quand sa prop label change, et arrête son minuteur quand elle est retirée.

Et le même composant sous forme de fonction. Chaque méthode de cycle de vie devient une partie d'un effet, et la mise en place et le nettoyage liés se trouvent côte à côte au lieu d'être répartis dans deux méthodes.

Les deux minuteurs comptent de la même façon et écrivent à chaque changement de libellé. La version fonction écrit aussi une fois au montage, puisqu'un effet s'exécute aussi après le premier rendu. Les étapes pour toute conversion :

  1. this.props.x devient une prop déstructurée, { x }.
  2. Chaque clé de this.state devient son propre useState. Rappelez-vous que le setter remplace au lieu de fusionner.
  3. Les méthodes deviennent de simples fonctions dans le composant. Aucune liaison nécessaire.
  4. componentDidMount, componentDidUpdate et componentWillUnmount deviennent des appels à useEffect, regroupés selon ce qu'ils font plutôt que selon le moment où ils s'exécutent.
  5. createRef devient useRef, et static contextType avec this.context devient useContext ou use.

Laissez les error boundaries sous forme de classes ; elles n'ont pas d'équivalent en fonction.

PureComponent

Un composant classe normal refait son rendu chaque fois que son parent le fait. PureComponent compare d'abord les nouvelles props et le nouvel état aux précédents, sur un niveau de profondeur, et saute le rendu quand rien n'a changé. C'est l'équivalent en classe de React.memo.

Cliquez sur le bouton : seul PlainLabel rendered s'affiche, car PureLabel voit le même text. Passez text={'hello ' + clicks} aux deux et les deux refont leur rendu à chaque clic.

La comparaison est superficielle, donc une prop qui est un nouvel objet ou une nouvelle fonction à chaque rendu du parent (style={{ color: 'red' }}, onClick={() => ...}) l'annule. C'est le même piège qu'avec React.memo.

Ce que React 19 a supprimé des classes

Si vous maintenez du vieux code à base de classes, quelques patterns ne fonctionnent plus dans React 19 :

  • Les string refs (ref="input" avec this.refs.input). Utilisez createRef() ou une ref callback.
  • Le contexte legacy (contextTypes, childContextTypes, getChildContext). Utilisez createContext avec static contextType.
  • propTypes est ignoré. Utilisez TypeScript ou vos propres vérifications.
  • findDOMNode a disparu. Placez plutôt une ref sur l'élément DOM.

Les anciennes méthodes componentWillMount, componentWillReceiveProps et componentWillUpdate sont aussi legacy. Elles s'exécutent encore, sous les anciens noms comme sous les noms UNSAFE_ (UNSAFE_componentWillMount et les autres), mais elles sont obsolètes et StrictMode avertit à leur sujet ; déplacez leur code dans componentDidMount, componentDidUpdate ou getDerivedStateFromProps.

Questions fréquentes

Les composants classes sont-ils obsolètes dans React ?

Non. Ils sont toujours pris en charge dans React 19 et continueront de fonctionner, mais la documentation de React recommande les composants fonctions avec hooks pour le nouveau code. Vous avez toujours besoin d'une classe pour les error boundaries.

Quelle est la différence entre composants classes et composants fonctions ?

Un composant classe garde l'état dans this.state, le met à jour avec this.setState et réagit au cycle de vie par des méthodes nommées. Un composant fonction utilise les hooks (useState, useEffect) pour les mêmes tâches, n'a pas besoin de this et est plus court.

setState met-il à jour l'état immédiatement ?

Non. this.setState planifie une mise à jour et React fait le rendu plus tard, donc this.state contient toujours l'ancienne valeur juste après l'appel. Passez une fonction, this.setState((state) => ...), quand la nouvelle valeur dépend de l'ancienne, ou lisez le résultat dans le callback passé en second argument ou dans componentDidUpdate.

Pourquoi this vaut-il undefined dans mon gestionnaire d'événement ?

Une méthode de classe passée sous la forme onClick={this.handleClick} est appelée sans son objet, donc this vaut undefined. Définissez le gestionnaire comme une fonction fléchée en champ de classe (handleClick = () => { ... }) ou liez-le dans le constructeur.

Qu'est-ce que PureComponent ?

Un Component qui saute le rendu quand ses props et son état sont superficiellement égaux aux précédents. C'est la version classe de React.memo.

Illustration des langages de programmation de Coddy

Apprendre à coder avec Coddy

COMMENCER