04

State (useState)

La mémoire interne réactive du composant

Le concept : Si les Props sont les données venant de l'extérieur, le State (état) est la mémoire interne et secrète du composant. C'est lui qui permet à un composant d'être interactif. Dès que le state d'un composant change (via sa fonction de mise à jour), React le remarque et redessine instantanément l'interface pour refléter cette nouvelle réalité.

setState() const [count] 0 1 2 0
💡 Pourquoi le State ?

En JS standard, changer une variable (let x = 1) ne met pas à jour l'écran automatiquement. React a besoin de savoir quand les données changent pour relancer le rendu.

Le State est la "mémoire" du composant. Quand vous appelez la fonction de mise à jour (setCount), React planifie un nouveau rendu du composant avec la nouvelle valeur. C'est ce qui rend l'interface réactive.

useState
import { useState } from 'react';

function Counter() {
    // [étatActuel, fonctionDeMiseAJour] = useState(valeurInitiale)
    const [count, setCount] = useState(0);

    return (
        <button onClick={() => setCount(count + 1)}>
            Clics : {count}
        </button>
    );
}
Mises à jour asynchrones
// ❌ Risqué si plusieurs mises à jour s'enchaînent
setCount(count + 1);
setCount(count + 1); // Ça n'ajoutera que 1 au total !

// ✅ Sûr : functional update (basé sur la valeur précédente)
setCount(prev => prev + 1);
setCount(prev => prev + 1); // Ajoute bien 2
Objets dans le State
const [user, setUser] = useState({ name: "Bob", age: 30 });

// ⚠️ Attention : React ne fusionne pas les objets automatiquement !
setUser({ ...user, age: 31 }); // Il faut copier le reste avec "..."
🚀 Concept : Lifting State Up

Si deux composants frères (ex: Sidebar et Header) ont besoin de la même donnée (ex: isMenuOpen), il faut "remonter" cet état vers leur parent commun le plus proche, puis le redescendre via les props.

Le parent détient le useState et passe la fonction setIsMenuOpen aux enfants.

📸 Analogie : L'Instantané (Snapshot)

Le State n'est pas une variable normale qui change "en direct".
C'est une photo prise au moment du rendu. Même si vous changez le State, la variable count dans la fonction actuelle ne change pas ! Elle changera au prochain rendu (la prochaine photo).

🚫 Anti-Pattern : Mutation Directe

// NE MARCHE PAS
user.name = "Alice";
// React ne voit pas le changement !

// IL FAUT REMPLACER L'OBJET
setUser({ ...user, name: "Alice" });
Concept : State Machine (Status)
// Au lieu de pleins de booléens (isLoading, isError, isSuccess...)
// Utilisez un seul string d'état pour éviter les états impossibles.
const [status, setStatus] = useState("idle"); // "loading" | "success" | "error"

return (
    <div>
        {status === "idle" && <StartBtn />}
        {status === "loading" && <Spinner />}
        {status === "error" && <ErrorMsg />}
    </div>
);
Démo State (Simulé)
0
Log cycle de vie