Aller au contenu principal

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...

  1. dans le dossier quiz-cyber-web, lancer npm run build et dire quel dossier est créé
  2. ouvrir src/main.tsx et dire ce que représente le composant App entre les balises <StrictMode>
  3. lancer npm run dev et 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.

src/components/EnTete.tsx
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 :

src/App.tsx
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 App utilise export default, comme dans le gabarit.

Le JSX : du HTML dans du JavaScript​

Le JSX ressemble beaucoup au HTML, avec quelques règles en plus :

HTMLJSXPourquoi
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 :

  1. un composant renvoie un seul élément racine. Pour renvoyer plusieurs éléments sans ajouter de <div> inutile, utilisez un fragment <>...</> ;
  2. les parenthèses après return permettent 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.

src/components/Carte.tsx
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>
);
}
  • titre est une prop (une donnée transmise au composant) ;
  • children contient tout ce qui est écrit entre la balise ouvrante et la balise fermante ;
  • ReactNode est 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.

Bonne pratique - Un composant, un seul rôle

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​


Quel est le nom correct de l'attribut qui applique une classe CSS en JSX ?


Pourquoi un composant ne peut-il pas renvoyer deux éléments voisins sans enveloppe ?


Comment affiche-t-on la variable joueur dans un paragraphe JSX ?


Quelle écriture applique un style en ligne rouge à un paragraphe ?


Que contient la prop children d'un composant ?


Comment doit s'écrire la balise de saut de ligne en JSX ?



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.


Bonne pratique - header pour l'en-tête

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.


Bonne pratique - import type

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.


Bonne pratique - Des imports triés

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>
);
}

Bonne pratique - Lire l'erreur de compilation

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​

NotionRésumé
ComposantFonction au nom commençant par une majuscule, qui renvoie du JSX.
JSXclassName, htmlFor, onClick, balises fermées, un seul élément racine (ou un fragment).
{ }Insère une expression JavaScript dans le JSX.
childrenLe contenu placé entre les balises d'un composant, de type ReactNode.
OrganisationUn 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.