JSX est une extension de syntaxe JavaScript qui permet d'écrire un balisage proche du HTML dans votre code. Les composants React renvoient du JSX pour décrire ce qui doit apparaître à l'écran, et un outil de build le compile en appels de fonction JavaScript ordinaires. Il ressemble au HTML, mais quelques règles diffèrent, et les accolades permettent d'insérer n'importe quelle valeur JavaScript dans le balisage.
Tout ce qui est entre {} est du JavaScript : une propriété, un appel de méthode, et même map qui transforme un tableau en éléments de liste. Ajoutez 'design' au tableau skills et le nombre comme la liste se mettent à jour.
Les règles du JSX
Renvoyer un seul élément racine
Un composant renvoie une seule valeur, son JSX a donc besoin d'un seul parent. Deux éléments frères au niveau supérieur sont une erreur de syntaxe. Si vous ne voulez pas de <div> supplémentaire dans la page, entourez-les d'un fragment, <>...</> :
// Error: Adjacent JSX elements must be wrapped in an enclosing tag
return (
<h1>Title</h1>
<p>Text</p>
);
// OK: a fragment groups them without adding a DOM element
return (
<>
<h1>Title</h1>
<p>Text</p>
</>
);
Si vous avez besoin d'une key sur le groupe, utilisez la forme longue <Fragment key={id}> ; voir fragments.
Fermer chaque balise
Le HTML permet de laisser certaines balises ouvertes. Pas le JSX. Les éléments sans enfants se ferment eux-mêmes avec /> : <img />, <br />, <input />, et vos propres composants comme <Avatar />.
Utiliser className, htmlFor et des attributs en camelCase
Les attributs JSX deviennent les clés d'un objet JavaScript, ils suivent donc le nommage JavaScript. class et for sont des mots réservés en JavaScript, c'est pourquoi le JSX utilise className et htmlFor. Les attributs de plusieurs mots et tous les gestionnaires d'événements sont en camelCase : tabIndex, maxLength, autoFocus, onClick, onChange. Deux exceptions gardent leurs tirets : les attributs aria-* et data-* s'écrivent exactement comme en HTML.
Remplacez className="field" par class="field". Le label garde son style, car React définit l'attribut quand même, mais un build de développement affiche "Invalid DOM property class. Did you mean className?" L'aperçu fonctionne comme un build de production, vous ne verrez donc pas cet avertissement ici ; utilisez className. Un attribut texte utilise des guillemets (type="email") ; toute autre valeur utilise des accolades (maxLength={40}, disabled={false}).
Les accolades acceptent des expressions, pas des instructions
Entre {}, vous pouvez écrire tout ce qui produit une valeur : une variable, un calcul, un appel de fonction, un ternaire, &&, un littéral de gabarit. Les instructions comme if, for et const ne produisent pas de valeur, elles ne peuvent donc pas s'y trouver. Faites le travail avant le return, ou utilisez une forme expression :
Regardez bien avant de cliquer : la page affiche un 0 égaré. count && <p>...</p> vaut 0 quand le compteur est à zéro, et React affiche les nombres, même zéro. Remplacez-le par count > 0 && <p>You have mail.</p> et le 0 disparaît. false, null, undefined et true n'affichent rien, c'est pourquoi un booléen à gauche de && est sans risque. La page sur le rendu conditionnel présente les différentes façons de faire.
Les styles inline utilisent un objet
L'attribut style prend un objet JavaScript, pas une chaîne CSS. D'où l'aspect « doubles accolades » : la paire extérieure signifie « du JavaScript ici », la paire intérieure est le littéral d'objet. Les noms de propriétés sont en camelCase (backgroundColor, fontSize), et un simple nombre signifie des pixels pour la plupart des propriétés de taille.
Comme le style est un objet, il peut être calculé à partir de l'état comme n'importe quelle autre valeur. Essayez de remplacer fontSize: big ? 24 : 16 par fontSize: big ? '2em' : '1em' : les chaînes sont transmises avec leur unité.
Commentaires
Un commentaire dans le JSX se place entre accolades : {/* this is a comment */}. Les commentaires HTML (<!-- -->) sont une erreur de syntaxe. En dehors du balisage, dans le corps de la fonction, les commentaires // habituels fonctionnent normalement.
return (
<div>
{/* The header is hidden on small screens */}
<Header />
</div>
);
Convertir du HTML en JSX
Coller du HTML dans un composant est une première étape courante, et la plupart du code fonctionne. Voici les modifications que vous devez généralement faire :
classdevientclassName, etfordevienthtmlFor.- Les balises vides se ferment elles-mêmes :
<br>devient<br />,<img src="a.png">devient<img src="a.png" />. style="color: red; font-size: 14px"devientstyle={{ color: 'red', fontSize: 14 }}.- Les attributs d'événement prennent une fonction, pas une chaîne :
onclick="save()"devientonClick={save}. - Les noms d'attributs passent en camelCase :
tabindexdevienttabIndex, et lestroke-widthdu SVG devientstrokeWidth. <!-- comments -->devient{/* comments */}.- Plusieurs éléments de premier niveau ont besoin d'un parent ou d'un fragment.
Les convertisseurs HTML vers JSX en ligne font ces étapes pour vous, mais les connaître rend les messages d'erreur faciles à comprendre quand vous en oubliez une.
Ce que devient le JSX après compilation
Les navigateurs ne savent pas exécuter le JSX. Un compilateur (comme Babel, SWC ou Oxc, que Vite et les frameworks lancent pour vous) transforme chaque balise en appel de fonction de react/jsx-runtime :
// What you write
const element = <h1 className="title">Hello, {name}</h1>;
const button = <Button size="small">OK</Button>;
// What the compiler produces (roughly)
import { jsx as _jsx, jsxs as _jsxs } from 'react/jsx-runtime';
const element = _jsxs('h1', { className: 'title', children: ['Hello, ', name] });
const button = _jsx(Button, { size: 'small', children: 'OK' });
Une balise en minuscules devient une chaîne ('h1', un élément HTML), une balise avec majuscule devient une référence à votre fonction (Button), les attributs deviennent l'objet props, et le contenu devient children. Les anciennes configurations compilaient plutôt vers React.createElement(type, props, ...children), c'est pourquoi les vieux fichiers commencent par import React from 'react' même s'ils ne mentionnent jamais React. L'appel renvoie un simple objet appelé élément React. Vous pouvez en afficher un dans la console :
La console montre que heading n'est que de la donnée : un type 'h3' et un objet props. C'est aussi pourquoi le JSX peut être stocké dans des variables, passé à des fonctions et renvoyé par elles.
Le JSX échappe le texte pour vous
Toute chaîne placée entre accolades est affichée comme du texte, jamais comme du HTML. Si un utilisateur tape <img src=x onerror=alert(1)> dans une zone de commentaire, React affiche ces caractères à l'écran au lieu de créer une balise image. Cela bloque par défaut la forme la plus courante de cross-site scripting (XSS).
Le premier paragraphe affiche les balises comme de simples caractères. Le second utilise dangerouslySetInnerHTML, qui saute l'échappement et insère la chaîne comme du vrai HTML, donc "our own" est en gras. Le nom à rallonge est un avertissement : ne passez que du HTML que vous avez produit vous-même ou nettoyé avec un assainisseur comme DOMPurify. Y passer une saisie utilisateur rouvre la faille XSS que le JSX avait fermée.
Questions fréquentes
Que signifie JSX ?
JSX signifie JavaScript XML. C'est une extension de syntaxe qui permet d'écrire, dans du code JavaScript, un balisage qui ressemble à du HTML.
Le JSX, est-ce du HTML ?
Non. Le JSX ressemble au HTML mais se compile en appels de fonction JavaScript qui créent des éléments React. C'est pourquoi il utilise className au lieu de class, des noms d'attributs en camelCase, et exige que chaque balise soit fermée.
Peut-on utiliser React sans JSX ?
Oui. Le JSX est facultatif : vous pouvez appeler directement createElement('h1', { className: 'title' }, 'Hello') depuis react. Presque toutes les bases de code React utilisent le JSX, car un balisage imbriqué est bien plus lisible.
Pourquoi ne peut-on pas mettre un if dans le JSX ?
Les accolades du JSX acceptent des expressions, c'est-à-dire des choses qui produisent une valeur, et if est une instruction. Utilisez un ternaire (cond ? a : b), &&, ou calculez la valeur dans une variable avant le return.
Comment écrire un commentaire en JSX ?
Entourez un commentaire JavaScript d'accolades : {/* like this */}. Les commentaires HTML (<!-- -->) sont une erreur de syntaxe en JSX.