JSX & Composants
Forge tes premières briques d'interface réutilisables.
2.1Démystifier le JSX : ce n'est pas du HTML
Le JSX ressemble à s'y méprendre à du HTML, mais c'est un leurre. Le navigateur web ne comprend pas le JSX. Sous le capot, c'est du pur JavaScript. Un outil de traduction (un compilateur, déjà configuré en coulisses dans ton projet) se charge de traduire automatiquement ton JSX en pur JavaScript classique.
// 1. Ce que tu écris dans ton composant (JSX) :
const element = <h1 className="titre">Bonjour Aventurier</h1>;
// 2. Ce que le compilateur génère réellement pour le navigateur :
const element = React.createElement(
"h1",
{ className: "titre" },
"Bonjour Aventurier"
);Puisque le JSX est en réalité du JavaScript, il y a quelques règles strictes à respecter pour ne pas lever d'erreurs :
⚠️ Les 3 règles d'or du JSX :
- Une seule balise parente : Une fonction JS ne peut retourner qu'une seule valeur. Tu ne peux pas retourner deux balises côte à côte sans les envelopper dans un parent (comme une
div) ou un Fragment vide (<> ... </>). - Fermer toutes les balises : En HTML, écrire
<img src="...">est toléré. En JSX, c'est une erreur fatale. Tu dois obligatoirement écrire une balise auto-fermante :<img src="..." />ou<input />. - Les attributs renommés : Comme
classetforsont des mots-clés réservés en JavaScript, en JSX tu dois écrireclassNameà la place de class, ethtmlForà la place de for.
2.2Rendre l'affichage dynamique
La vraie puissance du JSX réside dans sa capacité à fusionner la structure et la logique. Tu peux injecter n'importe quelle expression JavaScript (variable, calcul, condition, fonction) directement au milieu de ta structure en l'entourant d'accolades { } :
function FichePersonnage() {
const nom = "Kaelen";
const pointsDeVie = 82;
const classe = "Archer";
return (
<div className="fiche">
<h2>Nom : {nom}</h2>
<p>Classe : {classe}</p>
{/* 1. Un calcul dynamique en direct */}
<p>Points de vie après potion (+20) : {pointsDeVie + 20} HP</p>
{/* 2. Une condition ternaire pour le style ou le texte */}
<p className={pointsDeVie < 30 ? "Danger" : "Stable"}>
Statut : {pointsDeVie < 30 ? "⚠️ En danger !" : "Prêt au combat"}
</p>
</div>
);
}2.3Forger son premier composant
Un composant React est simplement une **fonction JavaScript qui retourne du JSX**. Il y a une convention absolue à suivre : son nom doit obligatoirement commencer par une **majuscule** (PascalCase) :
// ✅ Correction : Nom avec majuscule (PascalCase)
function BoutonAttaque() {
return (
<button className="bg-red-500 text-white font-bold p-3 rounded">
Lancer l'attaque !
</button>
);
}
// ❌ À éviter : minuscule au début. React le prendra pour
// une simple balise HTML standard et lèvera une erreur.
function boutonAttaque() {
return <button>Attaque</button>;
}React utilise la majuscule pour faire la distinction : si la balise commence par une minuscule (ex: <button>), il la traite comme une balise HTML standard. Si elle commence par une majuscule (ex: <BoutonAttaque />), il sait que c'est l'un de tes composants personnalisés.
2.4Les Props : configurer ses composants
Pour qu'un composant ne soit pas figé et puisse afficher des données différentes, on lui passe des **props** (propriétés). C'est l'équivalent des arguments d'une fonction classique, mais sous forme d'attributs dans le JSX.
Sur notre site moderne, on utilise TypeScript pour définir clairement le contrat (le type) de nos props :
// 1. On définit le type de nos props avec TypeScript
interface CarteProfilProps {
nom: string;
classe: string;
niveau: number;
}
// 2. Le composant récupère ses props (en les déstructurant en paramètre)
function CarteProfil({ nom, classe, niveau }: CarteProfilProps) {
return (
<div className="border p-4 rounded-xl shadow-sm bg-white">
<h3 className="text-lg font-bold">{nom}</h3>
<p className="text-slate-500">{classe} - Niveau {niveau}</p>
</div>
);
}
// 3. On appelle le composant en lui injectant les valeurs requises
function App() {
return (
<div className="flex gap-4">
<CarteProfil nom="Aria" classe="Soigneuse" niveau={12} />
<CarteProfil nom="Brok" classe="Guerrier" niveau={5} />
</div>
);
}2.5La règle d'or : les props sont en lecture seule
C'est le concept du **flux de données unidirectionnel** de React. Les données descendent des parents vers les enfants.
Règle absolue : Un composant ne doit JAMAIS modifier ses props directement. C'est une règle de pureté. Si un composant enfant reçoit niveau=12, il n'a pas le droit d'écrire niveau = 13. Les props sont en lecture seule (read-only). Si la valeur doit changer au cours du temps, c'est le rôle du State (qu'on verra au prochain chapitre).
2.6La prop spéciale children
React réserve un nom de prop spécial : children. Elle permet de capturer tout ce que tu insères **entre les balises d'ouverture et de fermeture** de ton composant. C'est parfait pour créer des conteneurs réutilisables (boîtes, modales, layouts) :
interface BoiteMonstreProps {
children: React.ReactNode; // Représente n'importe quel élément enfant
titreZone: string;
}
function BoiteMonstre({ children, titreZone }: BoiteMonstreProps) {
return (
<div className="bg-slate-50 border-2 border-slate-200 rounded-2xl p-6">
<h4 className="text-xs uppercase font-bold text-slate-400 mb-4">
Zone : {titreZone}
</h4>
{/* C'est ici que le contenu interne sera injecté */}
<div className="conteneur-interne">{children}</div>
</div>
);
}
// Utilisation :
function App() {
return (
<BoiteMonstre titreZone="Forêt Maudite">
{/* Tout ce qui est ici constitue la prop 'children' */}
<h5>Gobelin Farceur</h5>
<p>HP: 20 | XP: 50</p>
<button className="bg-red-100 text-red-700 px-3 py-1 rounded">Attaquer</button>
</BoiteMonstre>
);
}