React : composants, props et état
⏱ 65 minReact décompose l'UI en composants réutilisables. Chaque composant = une fonction qui retourne du JSX.
Composant fonctionnel de base
// Un composant = une fonction qui retourne du JSX
function ModuleCard({ icon, title, description, level }) {
return (
<div className="card p-6 hover:border-accent/50 transition-colors">
<span className="text-3xl">{icon}</span>
<h3 className="font-bold text-white mt-2">{title}</h3>
<p className="text-sm text-slate-400">{description}</p>
<span className="text-xs text-emerald-400">{level}</span>
</div>
);
}
// Utilisation
<ModuleCard icon="🐍" title="Python" description="Les bases" level="Débutant" />
useState — état local
import { useState } from "react";
function QuizQuestion({ question, options, answer }) {
const [selected, setSelected] = useState(null);
const [showResult, setShowResult] = useState(false);
return (
<div>
<p>{question}</p>
{options.map((opt, i) => (
<button
key={i}
onClick={() => setSelected(i)}
className={selected === i ? "bg-accent" : "bg-ink-800"}
>
{opt}
</button>
))}
<button onClick={() => setShowResult(true)}>Valider</button>
{showResult && (
<p>{selected === answer ? "✅ Correct !" : "❌ Incorrect"}</p>
)}
</div>
);
}
useEffect — effets de bord
import { useEffect, useState } from "react";
function Dashboard() {
const [progress, setProgress] = useState(null);
useEffect(() => {
// Exécuté après le rendu
const saved = JSON.parse(localStorage.getItem("progress") || "{}");
setProgress(saved);
}, []); // [] = exécuté une seule fois au montage
if (!progress) return <p>Chargement...</p>;
return <p>XP : {progress.xp}</p>;
}
Ressource : react.dev — https://react.dev (tutoriel officiel interactif)
📚 Pour aller plus loin
✍️ Exercices de la leçon
2 exercicesFais-les dans l'ordre, dans un vrai fichier .py — pas dans ta tête. Ne déplie la correction qu'après avoir écrit quelque chose, même faux.
Exercice A — Un composant de quiz avec état
Application directe · Tu appliques ce que tu viens de lire.
Écris un composant QuestionQuiz qui reçoit en props une question, un tableau d'options et l'index de la bonne réponse.
- 1.au clic sur une option, elle se sélectionne visuellement
- 2.un bouton « Valider » révèle la bonne et la mauvaise réponse, et désactive les options
- 3.après validation, un message et un bouton « Suivante »
- 4.le bouton « Valider » est désactivé tant qu'aucune option n'est choisie
- 5.le composant se réinitialise correctement quand la question change
Le point 5 est celui qui piège tout le monde : passe à la question suivante et regarde si la sélection précédente reste affichée.
Exercice B — Le composant qui ne se met pas à jour
Page blanche · Aucun squelette : à toi de choisir la méthode.
Page blanche. Diagnostic.
Ce composant ne réaffiche rien quand on ajoute une tâche. Le tableau est bien modifié — on le voit dans un console.log — mais l'écran ne bouge pas.
function ListeTaches() {
const [taches, setTaches] = useState([{ id: 1, texte: "Faire les exercices", faite: false }]);
const ajouter = (texte) => {
taches.push({ id: Date.now(), texte, faite: false });
setTaches(taches);
console.log(taches); // le tableau contient bien la nouvelle tâche
};
const basculer = (id) => {
const t = taches.find((x) => x.id === id);
t.faite = !t.faite;
setTaches(taches);
};
return <ul>{taches.map((t) => <li key={t.id}>{t.texte}</li>)}</ul>;
}
- 1.explique précisément pourquoi React ne réaffiche pas
- 2.corrige les deux fonctions
- 3.explique ce que React compare exactement pour décider de réafficher
- 4.donne la règle générale, applicable aussi aux objets et aux objets imbriqués
- 5.montre le même bug appliqué à un objet plutôt qu'à un tableau
Le `console.log` qui montre la bonne valeur est ce qui rend le bug si déroutant. La donnée est correcte, l'affichage non.