Composants et JSX
Construire une interface comme un jeu de briques : de petites fonctions qui se combinent.
Objectifs de la séance
- écrire un composant (une fonction qui renvoie du JSX) ;
- connaître les règles du JSX et ses différences avec le HTML ;
- insérer des valeurs dans le JSX avec les accolades ;
- exporter un composant et l'importer dans un autre fichier ;
- imbriquer des composants grâce à
children; - appliquer des styles avec
className.
Petite vérification
Avant de commencer, vérifiez si vous savez...
- dans le dossier
quiz-cyber-web, lancernpm run buildet dire quel dossier est créé - ouvrir
src/main.tsxet dire ce que représente le composantAppentre les balises<StrictMode> - lancer
npm run devet lire l'adresse locale affichée dans le terminal
📌 Réponse attendue
Notions théoriques
Un composant, c'est une fonction
Un composant est une fonction dont le nom commence par une majuscule et qui renvoie du JSX, la description de ce qu'il faut afficher.
export function EnTete() {
return (
<header className="entete">
<h1>Quiz Cyber</h1>
<p>Testez vos réflexes de sécurité</p>
</header>
);
}
Pour l'utiliser, on l'écrit comme une balise HTML portant son nom :
import { EnTete } from "./components/EnTete";
export default function App() {
return <EnTete />;
}
L'application est un arbre de composants : App contient EnTete, qui contient des balises HTML, etc.
Un fichier par composant
- le fichier porte le nom du composant :
EnTete.tsx; - il se range dans
src/components/; - on l'exporte avec
export(export nommé, comme vu dans le cours JavaScript) et on l'importe là où on en a besoin ; - seul
Apputiliseexport default, comme dans le gabarit.
Le JSX : du HTML dans du JavaScript
Le JSX ressemble beaucoup au HTML, avec quelques règles en plus :
| HTML | JSX | Pourquoi |
|---|---|---|
class="carte" | className="carte" | class est un mot réservé de JavaScript |
for="pseudo" | htmlFor="pseudo" | for est un mot réservé de JavaScript |
onclick="..." | onClick={...} | les attributs sont en camelCase |
<br> | <br /> | toute balise doit être fermée |
<!-- commentaire --> | {/* commentaire */} | un commentaire est une expression JavaScript |
style="color: red" | style={{ color: "red" }} | un style est un objet JavaScript |
Deux autres règles :
- un composant renvoie un seul élément racine. Pour renvoyer plusieurs éléments sans ajouter de
<div>inutile, utilisez un fragment<>...</>; - les parenthèses après
returnpermettent d'écrire le JSX sur plusieurs lignes.
export default function App() {
return (
<>
<EnTete />
<p>Deux éléments, un seul retour grâce au fragment</p>
</>
);
}
Les accolades : insérer du JavaScript
Les accolades { } insèrent une expression JavaScript (variable, calcul, appel de fonction).
const joueur = "Alice";
const score = 7;
<p>Bravo {joueur} ! Votre score : {score * 10} points</p>
Elles ne permettent pas d'écrire des instructions (if, for) : seulement des valeurs. Pour une condition, on utilise le ternaire ; pour une liste, map (prochaine séance).
children : un composant qui en contient un autre
Une balise HTML peut contenir d'autres balises. Un composant aussi, à condition de dire où les placer avec la propriété spéciale children.
import type { ReactNode } from "react";
type CarteProps = {
titre: string;
children: ReactNode;
};
export function Carte({ titre, children }: CarteProps) {
return (
<section className="carte">
<h2>{titre}</h2>
{children}
</section>
);
}
titreest une prop (une donnée transmise au composant) ;childrencontient tout ce qui est écrit entre la balise ouvrante et la balise fermante ;ReactNodeest le type TypeScript qui désigne « n'importe quoi que React peut afficher » (texte, élément, liste...).
<Carte titre="Question 1">
<p>Quel mot de passe est le plus robuste ?</p>
</Carte>
Les styles : className et un fichier CSS
Les styles de ce cours sont dans src/index.css, importé une fois dans main.tsx. Chaque élément choisit ses styles avec className, comme vous le feriez avec class en HTML.
EnTete affiche le titre, Carte encadre un contenu. Si un composant fait deux choses différentes, découpez-le : les petits composants sont plus faciles à relire et à réutiliser.
Test de mémorisation/compréhension
TP pour réfléchir et résoudre des problèmes
Votre mission : construire l'en-tête du quiz et une carte réutilisable.
Étape 1 — Le composant EnTete
Créez le dossier src/components/ et le fichier EnTete.tsx.
Utilisez les balises HTML qui ont un sens (header, section, main, nav) plutôt que des div partout : c'est meilleur pour l'accessibilité et le référencement.
Étape 2 — Le composant Carte avec children
Créez Carte.tsx : une carte qui reçoit un titre et un contenu.
Le gabarit active verbatimModuleSyntax : un type s'importe avec import type. L'outil sait ainsi qu'il peut effacer cette ligne du code final.
Étape 3 — Assembler dans App
Affichez l'en-tête puis une carte contenant une question, avec un fragment.
Rangez les imports en haut du fichier, par ordre alphabétique : on voit tout de suite de quels composants dépend App.
Étape 4 — Corriger du JSX invalide
Le composant ci-dessous contient trois erreurs de JSX. Corrigez-les puis vérifiez avec npm run build.
export function Alerte() {
return (
<div class="alerte">
<p>Attention</p>
<br>
</div>
<p>Fin</p>
);
}
Vite affiche une page d'erreur dans le navigateur avec le fichier et la ligne : lisez-la avant de modifier le code au hasard.
📌 Une solution
Ce qu'il faut retenir
| Notion | Résumé |
|---|---|
| Composant | Fonction au nom commençant par une majuscule, qui renvoie du JSX. |
| JSX | className, htmlFor, onClick, balises fermées, un seul élément racine (ou un fragment). |
{ } | Insère une expression JavaScript dans le JSX. |
children | Le contenu placé entre les balises d'un composant, de type ReactNode. |
| Organisation | Un composant par fichier dans src/components/, export nommé. |
Aperçu de la prochaine séance
Vos composants affichent un texte écrit « en dur ». Dans la prochaine séance, vous allez les alimenter avec des données typées : les props, les listes avec map et key, et les conditions pour afficher les questions du quiz.