React : composants et JSX
Un composant est une fonction qui renvoie du JSX (du HTML dans du JavaScript). Son nom commence par une majuscule.
function Salutation() { const nom = 'Alice'; const actif = true; return ( <section className="carte"> <h2>Bonjour {nom}</h2> <p style={{ color: actif ? 'green' : 'gray' }}> {actif ? 'Connectée' : 'Hors ligne'} </p> <label htmlFor="champ">Nom</label> <input id="champ" type="text" /> </section> );}Différences avec le HTML : className (et non class), htmlFor (et non for), attributs en camelCase (onClick, tabIndex), balises toujours fermées (<input />), un seul élément racine par composant.
Une expression entre accolades {…} peut contenir n’importe quelle expression JavaScript, pas d’instruction (if, for).
type Props = { titre: string; prix: number; enStock?: boolean;};
function Produit({ titre, prix, enStock = true }: Props) { return ( <article> <h3>{titre}</h3> <p>{prix.toFixed(2)} €</p> {!enStock && <p>Rupture de stock</p>} </article> );}
<Produit titre="Clavier" prix={49} />;Les props sont en lecture seule : un composant ne les modifie jamais.
Enfants et composition
Section intitulée « Enfants et composition »import type { ReactNode } from 'react';
function Carte({ titre, children }: { titre: string; children: ReactNode }) { return ( <section className="carte"> <h2>{titre}</h2> {children} </section> );}
<Carte titre="Profil"> <p>Contenu passé entre les balises.</p></Carte>;La composition (passer des éléments en children ou en props) est préférée à l’héritage.
Listes et clés
Section intitulée « Listes et clés »type Client = { id: number; nom: string };
function Liste({ clients }: { clients: Client[] }) { return ( <ul> {clients.map((c) => ( <li key={c.id}>{c.nom}</li> ))} </ul> );}La prop key identifie chaque élément : elle doit être stable et unique parmi les frères (un identifiant de la donnée). Éviter l’index du tableau si la liste peut être réordonnée, filtrée ou modifiée.
Rendu conditionnel
Section intitulée « Rendu conditionnel »function Statut({ erreur, chargement, donnees,}: { erreur?: string; chargement: boolean; donnees?: string[];}) { if (chargement) return <p>Chargement…</p>; if (erreur) return <p role="alert">Erreur : {erreur}</p>; if (!donnees?.length) return <p>Aucun résultat.</p>; return ( <ul> {donnees.map((d) => ( <li key={d}>{d}</li> ))} </ul> );}Attention à {nombre && <p>…</p>} : si nombre vaut 0, React affiche « 0 ». Écrire {nombre > 0 && …}.
Fragments
Section intitulée « Fragments »function Lignes() { return ( <> <tr> <td>A</td> </tr> <tr> <td>B</td> </tr> </> );}<>…</> regroupe des éléments sans ajouter de balise au DOM.
Organiser les composants
Section intitulée « Organiser les composants »src/├── components/ # composants réutilisables (Bouton, Carte, Modal)├── pages/ ou routes/ # composants d'écran├── hooks/ # hooks personnalisés (useXxx)├── lib/ # fonctions utilitaires, clients d'API└── types/- Un composant par fichier, nommé comme le composant.
- Exporter par défaut pour les pages, nommé pour les composants partagés (au choix, mais cohérent).
- Séparer présentation (affichage) et logique (hooks, appels d’API) quand un composant grossit.
import './Carte.css'; // CSS classique<div className="carte carte--active" />;<div style={{ width: `${pourcent}%` }} />; // style dynamiqueAvec Tailwind : classes utilitaires dans className (voir Tailwind : utilitaires et Organisation et composants).
Accessibilité de base
Section intitulée « Accessibilité de base »- Utiliser les balises sémantiques (
button,nav,main,label) plutôt que desdivcliquables. - Toujours un
altsur<img>(vide si décorative). - Associer chaque champ à un
<label>. - Gérer le focus et le clavier pour les composants personnalisés (menu, boîte de dialogue).
Dépannage
Section intitulée « Dépannage »| Symptôme | Piste |
|---|---|
Warning: Each child in a list should have a unique "key" prop |
Ajouter key à l’élément de map |
Adjacent JSX elements must be wrapped |
Entourer par un fragment <>…</> |
Le composant s’affiche comme du texte (<monComposant>) |
Nom en minuscule : première lettre en majuscule |
Objects are not valid as a React child |
Afficher un objet : afficher ses champs ou JSON.stringify |
0 affiché |
{n && …} avec n valant 0 |
Cannot read properties of undefined |
Donnée pas encore chargée : prévoir l’état de chargement |
Ubuntu 24.04 et 26.04 : différences à connaître
Section intitulée « Ubuntu 24.04 et 26.04 : différences à connaître »Aucune.
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Décrire l’interface
- Suite : État et effets