Composants, JSX et props
React est une bibliothèque JavaScript pour construire des interfaces à partir de composants : des fonctions qui reçoivent des données et décrivent ce qui doit s’afficher. Quand les données changent, React met à jour le DOM pour vous.
Démarrer un projet
Create React App est abandonné. Pour apprendre, on utilise Vite ; pour une application complète, un framework comme Next.js ou React Router.
npm create vite@latest ma-boutique -- --template react
cd ma-boutique && npm install && npm run dev
Le modèle actuel installe React 19.3 et Vite 8 ; npm run lint lance oxlint, un linter qui applique notamment les règles des hooks.
Un premier composant
function Bienvenue() {
return <h1>Bienvenue dans la boutique</h1>;
}
export default function App() {
return (
<main>
<Bienvenue />
<Bienvenue />
</main>
);
}
Un composant est une fonction dont le nom commence par une majuscule (sinon React le prend pour une balise HTML). On l’utilise comme une balise : <Bienvenue />.
Les règles du JSX
Le JSX ressemble à du HTML mais il est compilé en JavaScript (<h1> devient un appel à une fonction de React). D’où quelques règles :
function Fiche() {
const nom = "Vélo de ville";
const prix = 499;
return (
<> {/* fragment : un seul parent, sans div inutile */}
<h2 className="titre">{nom}</h2> {/* className et non class */}
<p>{prix * 1.2} € TTC</p> {/* toute expression entre accolades */}
<label htmlFor="qte">Quantité</label>
<input id="qte" type="number" defaultValue={1} /> {/* balises toujours fermées */}
<p style={{ color: "green" }}>En stock</p> {/* style : un objet */}
</>
);
}
Entre accolades, on met une expression (variable, calcul, appel de fonction, ternaire), pas une instruction if ou for.
Les props
Les props sont les paramètres d’un composant. On les reçoit dans un objet, généralement déstructuré :
function CarteProduit({ nom, prix, enStock = true }) { // valeur par défaut
return (
<article>
<h2>{nom}</h2>
<p>{prix} €</p>
{!enStock && <p>Rupture de stock</p>}
</article>
);
}
<CarteProduit nom="Casque" prix={39} enStock={false} />
Les chaînes se passent entre guillemets, toutes les autres valeurs entre accolades : prix={39}, enStock={false}, options={{ couleur: "rouge" }}.
Les props sont en lecture seule : un composant ne doit jamais les modifier.
children
Ce qui est placé entre la balise ouvrante et fermante arrive dans la prop children :
function Carte({ titre, children }) {
return (
<section className="carte">
<h2>{titre}</h2>
{children}
</section>
);
}
<Carte titre="Livraison">
<p>Offerte dès 50 € d'achat.</p>
</Carte>
C’est la base de la composition : de petits composants génériques assemblés en interfaces complètes.
Des composants purs
Un composant doit se comporter comme une fonction pure : avec les mêmes props, il renvoie le même JSX, sans modifier de variable extérieure ni appeler d’API pendant le rendu. Les effets de bord ont leur place dans les gestionnaires d’événements ou les effets (leçon 4). En mode développement, <StrictMode> appelle volontairement deux fois vos composants pour révéler les impuretés.
À retenir
- Composant = fonction en Majuscule qui renvoie du JSX.
{expression},className, balises fermées, un seul parent.- Props en lecture seule,
childrenpour composer.
Exercices
Les solutions et les tests restent sur le serveur. Dans l'espace étudiant, ton code est exécuté et corrigé, et le tuteur donne des indices avant la solution.
Carte produit
Écrivez le composant
CarteProduit({ nom, prix, enStock = true })qui affiche :- un
<article>contenant un<h2>avec le nom ; - un paragraphe avec le prix formaté par
formaterPrix(prix)(fournie) ; - un paragraphe
Rupture de stockuniquement sienStockest faux ; - un bouton
Ajouter au panier, désactivé (disabled) en cas de rupture.
const formaterPrix = (p) => new Intl.NumberFormat("fr-FR", { style: "currency", currency: "EUR" }).format(p); export function CarteProduit({ nom, prix, enStock = true }) { // TODO }- un
Formater un prix (exécuté)
Fonction pure utilisée par vos composants. Écrivez
formaterPrix(prix)qui renvoie le prix au format français en euros avecIntl.NumberFormat(12.5→"12,50 €").Attention :
Intlinsère une espace insécable avant€; les tests normalisent les espaces.function formaterPrix(prix) { // TODO }Règles du JSX
Lequel de ces extraits est du JSX valide ?
- <div class="carte"><img src={url}></div>
- <><label htmlFor="q">Recherche</label><input id="q" /></>
- <p>{if (ok) { "Oui" }}</p>
- <h1>Titre</h1><p>Texte</p> (renvoyés côte à côte sans parent)
Quiz de fin de leçon
Pourquoi le nom d’un composant doit-il commencer par une majuscule ?
- Par convention esthétique seulement
- Pour que React le distingue d'une balise HTML native
- Pour qu'il soit exporté automatiquement
Que contient la prop children ?
- Les composants enfants déclarés dans le fichier
- Le contenu placé entre la balise ouvrante et la balise fermante du composant
- La liste des props
Un composant peut-il modifier ses props ?
- Oui, c'est le moyen normal de mettre à jour l'affichage
- Non, les props sont en lecture seule
- Oui, mais seulement children
La suite du cours
- L'état avec useState et les événements18 min
- Listes, rendu conditionnel et état partagé18 min
- Effets, synchronisation et chargement de données20 min
- useReducer, Context et hooks personnalisés20 min
- Formulaires et Actions avec React 1920 min