Initialisation des systèmes...

Baptiste.Dev
Retour aux notes
FrameworksIntermédiaireSérie : React / Next.js

React : Le state et les hooks

Donner de la mémoire à un composant avec useState : l'état qui déclenche le re-rendu, la règle d'or de l'immutabilité, et les règles des hooks. Le cœur de l'interactivité React.

Par Baptiste Vidal
4 min de lecture
Mis à jour il y a 2 semaines
reactstatehooksusestatefrontend

React : Le state et les hooks

On a vu que les props sont en lecture seule : un composant les reçoit, il ne les change pas. Mais une interface, ça bouge : un compteur s'incrémente, un menu s'ouvre, un champ se remplit. Il faut donc une donnée qui évolue dans le temps et qui, quand elle change, met à jour l'affichage. C'est le state.


# Le state : la mémoire d'un composant

Une variable normale ne suffit pas : à chaque re-rendu, la fonction du composant est ré-exécutée, et la variable repart de zéro. Il faut une mémoire qui survit aux rendus. C'est le rôle du hook useState.

import { useState } from "react";
 
function Compteur() {
  const [compte, setCompte] = useState(0);
 
  return (
    <div>
      <span>Compte : {compte}</span>
      <button onClick={() => setCompte(compte + 1)}>+1</button>
    </div>
  );
}

useState(0) fait trois choses :

  • il crée une variable d'état, initialisée à 0 (la valeur passée) ;
  • il renvoie sa valeur actuelle (compte) ;
  • et une fonction pour la modifier (setCompte).

C'est exactement le compteur qu'on avait bricolé à la main en JavaScript... mais sans la fonction afficher() à rappeler soi-même.


# [valeur, setValeur] : une destructuration

useState renvoie un tableau de deux éléments, qu'on récupère par destructuration :

const [compte, setCompte] = useState(0);
// équivaut à :
// const resultat = useState(0);
// const compte = resultat[0];
// const setCompte = resultat[1];

Par convention, on nomme le setter setXxx (comptesetCompte).


# Ce qui rend React « réactif » : le re-rendu

Le point clé : modifier le state via son setter déclenche un re-rendu. React ré-exécute la fonction du composant, recalcule le JSX, et met à jour le DOM - uniquement ce qui a changé.

Corollaire crucial : modifier une variable normale ne déclenche rien.

function Compteur() {
  let compte = 0; // ❌ une variable normale
 
  return (
    <button onClick={() => {
      compte++;            // la variable change en mémoire...
      console.log(compte); // ...mais l'affichage ne bouge JAMAIS
    }}>
      {compte}
    </button>
  );
}

Sans useState, React ne sait pas que quelque chose a changé. Le state est le signal qui lui dit « re-rends ».


# La règle d'or : on ne mute jamais le state

Pour les objets et les tableaux, il ne faut pas les modifier en place, mais en créer une nouvelle version. React détecte un changement en comparant les références : si tu mutes l'ancien tableau, sa référence ne change pas, et React ne re-rend pas.

const [taches, setTaches] = useState(["Coder"]);
 
// ❌ Mutation : même référence, React ne voit rien
taches.push("Tester");
setTaches(taches);
 
// ✅ Nouvelle référence via le spread
setTaches([...taches, "Tester"]);

C'est le principe d'immutabilité vu côté JavaScript : on remplace, on ne modifie pas.

Quand le nouveau state dépend de l'ancien, préfère la forme fonction : setCompte(c => c + 1). React te passe la valeur la plus à jour, ce qui évite des bugs quand plusieurs mises à jour s'enchaînent.


# Qu'est-ce qu'un hook, au juste ?

Un hook est une fonction fournie par React dont le nom commence par use (useState, useEffect, useRef...). Elle permet de « se brancher » sur des fonctionnalités de React - l'état, le cycle de vie - depuis un composant.

Deux règles à respecter, sinon React s'y perd :

  • Appeler les hooks au niveau racine du composant - jamais dans une condition, une boucle ou une fonction imbriquée.
  • Uniquement depuis un composant (ou depuis un autre hook), pas depuis une fonction ordinaire.
// ❌ Interdit : hook dans une condition
if (connecte) {
  const [nom, setNom] = useState("");
}
 
// ✅ Toujours au sommet du composant
const [nom, setNom] = useState("");

Pourquoi ? React associe chaque useState à un rendu par son ordre d'appel. Si l'ordre change d'un rendu à l'autre, il mélange les états. (C'est aussi pour ça qu'une closure capture le state du rendu où elle a été créée.)


# À retenir

  • Le state est la mémoire d'un composant : une donnée qui survit aux rendus et déclenche une mise à jour quand elle change.
  • useState renvoie [valeur, setter] ; c'est le setter qui provoque le re-rendu - muter une variable normale ne fait rien.
  • On ne mute jamais le state : on en crée une nouvelle version (spread), car React compare les références.
  • Les hooks (useXxx) s'appellent toujours au niveau racine d'un composant.

Prochaine étape : faire changer ce state et adapter l'affichage, avec Les événements et le rendu conditionnel.