JSX est une extension de syntaxe de type XML pour JavaScript, développée par l’équipe React pour décrire déclarativement les interfaces utilisateur. Contrairement aux moteurs de templates, JSX se compile en appels de fonctions JavaScript ordinaires, offrant toute la puissance du langage à l’intérieur du balisage. Selon React, 2024, JSX est pris en charge dans tous les frameworks et bibliothèques React modernes.
Points clés
JSX (JavaScript XML) est une extension de syntaxe pour JavaScript, introduite pour la première fois dans React en 2013. Elle permet aux développeurs de décrire la structure d’une interface utilisateur de manière déclarative, en combinant balisage et logique dans un seul fichier.
Avant JSX, les développeurs utilisaient des modèles de chaînes (Mustache, Handlebars) ou créaient des éléments DOM manuellement via document.createElement. Les deux approches avaient des inconvénients : les modèles de chaînes n’étaient pas vérifiés par type, et la création manuelle du DOM était lourde et sujette aux erreurs.
React a choisi une voie différente — intégrer le balisage directement dans le code. Cette décision a suscité des débats dans la communauté, mais avec le temps, elle est devenue la norme. Aujourd’hui, JSX est utilisé non seulement dans React, mais aussi dans SolidJS, Preact, Qwik et même dans Vue via des plugins.
Un élément JSX ressemble à une balise HTML mais est intégré directement dans JavaScript. Chaque élément est transpilé en un appel React.createElement avec trois arguments : le type d’élément, l’objet props et les enfants. Un élément racine est une règle obligatoire : une expression JSX doit retourner un élément parent ou un fragment.
import React from 'react';
// JSX de base - élément racine unique
const element = (
<div className="app">
<h1>Hello, World!</h1>
<p>Welcome to React</p>
</div>
);
Lorsqu’aucun nœud DOM supplémentaire n’est nécessaire, utilisez React.Fragment ou la syntaxe abrégée <></>. Les fragments ne créent pas d’élément DOM réel, ils ne font que regrouper les nœuds enfants. Ceci est particulièrement utile dans les tableaux et les listes où un wrapper supplémentaire briserait la structure HTML.
function Columns() {
return (
<>
<td>First</td>
<td>Second</td>
</>
);
}
Toute expression JavaScript est intégrée dans JSX via des accolades { }. À l’intérieur, vous pouvez utiliser des variables, des appels de fonction, des opérateurs ternaires et des méthodes de tableau. Le rendu conditionnel est effectué via l’opérateur ternaire ou le ET logique.
function Greeting({ name, isLoggedIn }) {
const items = ['Red', 'Green', 'Blue'];
return (
<div>
{/* Expression with variable */}
<h1>Hello, {name}</h1>
{/* Conditional rendering */}
{isLoggedIn ?
<p>Welcome back!</p :
<button>Login</button>
}
{/* Render array */}
<ul>
{items.map(item =>
<li key={item}>{item}</li>
)}
</ul>
</div>
);
}
Une limitation clé — seules les expressions peuvent être utilisées à l’intérieur des accolades, pas les instructions. Vous ne pouvez pas utiliser if/else, for, switch — seulement l’opérateur ternaire, les opérateurs logiques et les méthodes de tableau. Les appels de fonction sont autorisés, y compris les fonctions fléchées.
JSX ressemble visuellement à HTML mais a des différences fondamentales. Les attributs s’écrivent en camelCase — className au lieu de class, onClick au lieu d’onclick, tabIndex au lieu de tabindex. Cela vient du fait que JSX se transpile en JavaScript, où les traits d’union dans les noms de propriétés ne sont pas autorisés.
| HTML | JSX | Raison |
|---|---|---|
class="wrapper" | className="wrapper" | class est un mot réservé en JS |
onclick="handle()" | onClick={handle} | camelCase pour les propriétés JS |
style="color: red" | style={{ color: ‘red’ }} | Objet de style au lieu de chaîne |
<input disabled> | <input disabled={true}> | Attributs booléens explicites |
Une autre différence importante — les balises auto-fermantes. En HTML, certaines balises (br, hr, input) peuvent rester non fermées. En JSX, toutes les balises auto-fermantes doivent avoir une barre oblique de fermeture : <br />, <input />. Les noms d’attributs SVG sont également convertis en camelCase : strokeWidth, fillOpacity.
Les navigateurs ne comprennent pas JSX directement. Avant l’exécution, le code JSX passe par un transpileur — Babel, TypeScript ou esbuild. Chaque élément JSX est transformé en un appel createElement ou jsx/runtime.
// JSX original
const element = <h1 className="title">Hello</h1>;
// Après transpilation
const element = React.createElement(
'h1',
{ className: 'title' },
'Hello'
);
Avec React 17, une nouvelle transformation JSX est apparue qui ne nécessite pas d’importer React. L’importation automatique de jsx-runtime permet d’écrire des composants sans import React from ‘react’. Babel et TypeScript prennent en charge cette transformation via la configuration {"runtime": "automatic"}.
Bien que JSX soit associé à React, d’autres frameworks l’utilisent également. SolidJS utilise JSX avec compilation en nœuds DOM réels, sans Virtual DOM. Preact est une alternative légère à React avec un support complet de JSX. Vue prend en charge JSX via @vue/babel-plugin-jsx, bien que son template principal soit template.
Une différence clé est la sémantique des expressions. Dans React, les expressions JSX sont exécutées à chaque rendu. Dans SolidJS, JSX se compile une fois et les mises à jour sont suivies via des signaux. Cela affecte les performances : SolidJS ne nécessite pas de Virtual DOM ni de réconciliation, ce qui rend le rendu JSX plus rapide.
Dans TypeScript, JSX est pris en charge au niveau du langage. Les fichiers avec l’extension .tsx traitent automatiquement la syntaxe JSX. Le typage des props est l’un des principaux avantages de TypeScript + JSX : l’IDE suggère les attributs attendus, les types de callbacks et le caractère obligatoire des props.
Écrivez du code JSX facile à lire et à maintenir. Extrayez les expressions complexes dans des variables ou fonctions séparées — cela améliore la lisibilité et permet de tester la logique séparément du balisage. Utilisez des fragments au lieu de wrappers div inutiles.
La règle d’indentation — maintenez l’indentation pour les éléments imbriqués. Chaque niveau d’imbrication est un niveau d’indentation. La balise de fermeture doit être au même niveau que la balise d’ouverture. Pour les attributs longs, utilisez des sauts de ligne.
Évitez les fonctions fléchées en ligne dans les props si elles sont créées à chaque rendu. Dans ce cas, enveloppez le callback dans useCallback ou déplacez la fonction en dehors du composant. Divisez les composants complexes en plus petits — chaque composant doit gérer une unité logique de l’interface.
Questions fréquentes
Oui, grâce au plugin Babel @babel/plugin-transform-react-jsx, JSX peut être configuré pour n’importe quelle bibliothèque. SolidJS, Preact, Nerv et d’autres frameworks utilisent JSX avec leur propre environnement d’exécution. Pour une indépendance totale, vous pouvez définir le pragma sur votre propre fonction.
class est un mot réservé en JavaScript. JSX se transpile en createElement, où le second argument passe un objet props. La propriété class entre en conflit avec la syntaxe de classe ES6, donc React a choisi className.
Utilisez les littéraux de gabarit ou la bibliothèque classnames : className={`btn ${isActive ? ‘active’ : ‘’}`}. Pour une logique complexe, installez le paquet npm clsx ou classnames, qui acceptent les objets et les tableaux.
JSX ne prend en charge que les expressions, pas les instructions. Pour les conditions, utilisez l’opérateur ternaire, le ET logique (&&) ou le OU logique (||). Pour une logique complexe, extrayez la condition dans une variable ou fonction séparée.
L’attribut key aide React à identifier les éléments de liste lors du re-rendu. Sans key, React re-rend toute la liste lors d’un changement. Avec une key unique, React réutilise les nœuds DOM et réordonne les éléments au lieu de les recréer.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi