Table of Contents

Chapitre 2 : JSX

Qu'est-ce que JSX ?

JSX (JavaScript XML) est une extension de syntaxe qui permet d'écrire du HTML dans JavaScript :

snippet.javascript
const element = <h1>Bonjour le monde !</h1>;

Ce n'est pas du HTML. C'est du JavaScript qui sera transformé en appels de fonctions React.

snippet.javascript
// Ce JSX :
const element = <h1 className="title">Bonjour</h1>;
 
// Est transformé en :
const element = React.createElement('h1', { className: 'title' }, 'Bonjour');

Vous n'avez pas besoin d'écrire React.createElement - le compilateur (Babel/Vite) le fait pour vous.

Différences avec HTML

className au lieu de class

class est un mot réservé en JavaScript :

snippet.javascript
// HTML
<div class="container">
 
// JSX
<div className="container">

htmlFor au lieu de for

snippet.javascript
// HTML
<label for="email">
 
// JSX
<label htmlFor="email">

Style en objet

snippet.javascript
// HTML
<div style="color: red; font-size: 16px;">
 
// JSX - objet avec camelCase
<div style={{ color: 'red', fontSize: '16px' }}>
 
// Ou avec une variable
const styles = { color: 'red', fontSize: '16px' };
<div style={styles}>

Attributs en camelCase

snippet.javascript
// HTML
<button onclick="handleClick()">
<input tabindex="1">
 
// JSX
<button onClick={handleClick}>
<input tabIndex={1}>

Fermeture obligatoire des balises

snippet.javascript
// HTML
<img src="photo.jpg">
<input type="text">
<br>
 
// JSX - toujours fermer
<img src="photo.jpg" />
<input type="text" />
<br />

Expressions JavaScript dans JSX

Utilisez les accolades {} pour insérer du JavaScript :

Variables

snippet.javascript
const name = "Jean";
const age = 30;
 
return (
    <div>
        <p>Nom : {name}</p>
        <p>Age : {age}</p>
        <p>Année de naissance : {2024 - age}</p>
    </div>
);

Fonctions

snippet.javascript
function formatName(user) {
    return `${user.firstName} ${user.lastName}`;
}
 
const user = { firstName: 'Jean', lastName: 'Dupont' };
 
return <h1>Bonjour, {formatName(user)} !</h1>;

Expressions, pas de statements

Dans les accolades, vous pouvez mettre des expressions (qui retournent une valeur), pas des statements (if, for, while).

snippet.javascript
// CORRECT - expressions
{name}
{2 + 2}
{formatName(user)}
{isAdmin ? 'Admin' : 'User'}
{items.length}
 
// INCORRECT - statements
{if (isAdmin) { return 'Admin' }}  // Erreur !
{for (let i = 0; i < 10; i++) {}}  // Erreur !

Conditions

Opérateur ternaire

Pour afficher une chose ou une autre :

snippet.javascript
function Greeting({ isLoggedIn }) {
    return (
        <div>
            {isLoggedIn ? (
                <p>Bienvenue !</p>
            ) : (
                <p>Veuillez vous connecter</p>
            )}
        </div>
    );
}

Opérateur &&

Pour afficher quelque chose ou rien :

snippet.javascript
function Notification({ count }) {
    return (
        <div>
            {count > 0 && (
                <span className="badge">{count}</span>
            )}
        </div>
    );
}

Attention : {count && <span>...</span>} affichera 0 si count vaut 0, car 0 est une valeur “falsy” mais affichable. Préférez {count > 0 && ...}.

Variables pour les cas complexes

snippet.javascript
function UserStatus({ user }) {
    let statusMessage;
 
    if (user.isAdmin) {
        statusMessage = <span className="admin">Administrateur</span>;
    } else if (user.isPremium) {
        statusMessage = <span className="premium">Premium</span>;
    } else {
        statusMessage = <span>Standard</span>;
    }
 
    return <div>{statusMessage}</div>;
}

Boucles avec map()

Pour afficher une liste, utilisez map() :

snippet.javascript
function UserList({ users }) {
    return (
        <ul>
            {users.map(user => (
                <li key={user.id}>
                    {user.name}
                </li>
            ))}
        </ul>
    );
}

L'attribut key

Obligatoire pour les listes. Permet à React d'identifier chaque élément :

snippet.javascript
// CORRECT - ID unique
{users.map(user => (
    <li key={user.id}>{user.name}</li>
))}
 
// ACCEPTABLE - si pas d'ID, utiliser l'index (moins performant)
{items.map((item, index) => (
    <li key={index}>{item}</li>
))}
 
// INCORRECT - pas de key
{users.map(user => (
    <li>{user.name}</li>  // Warning React !
))}

Comparaison avec PHP

snippet.php
// PHP
<?php foreach ($users as $user): ?>
    <li><?= $user['name'] ?></li>
<?php endforeach; ?>
snippet.javascript
// React
{users.map(user => (
    <li key={user.id}>{user.name}</li>
))}

Fragments

Un composant doit retourner un seul élément racine. Si vous ne voulez pas ajouter de <div> inutile, utilisez un Fragment :

snippet.javascript
// INCORRECT - plusieurs éléments racine
function UserInfo({ user }) {
    return (
        <h1>{user.name}</h1>
        <p>{user.email}</p>  // Erreur !
    );
}
 
// CORRECT - avec Fragment
function UserInfo({ user }) {
    return (
        <>
            <h1>{user.name}</h1>
            <p>{user.email}</p>
        </>
    );
}
 
// Ou la syntaxe longue
import { Fragment } from 'react';
 
function UserInfo({ user }) {
    return (
        <Fragment>
            <h1>{user.name}</h1>
            <p>{user.email}</p>
        </Fragment>
    );
}

Exercices

Exercice 1 : Convertir en JSX

Convertir ce HTML en JSX :

snippet.html
<div class="card">
    <img src="photo.jpg" alt="Photo">
    <label for="name">Nom :</label>
    <input type="text" id="name" tabindex="1">
    <button onclick="save()">Sauvegarder</button>
</div>

Solution :

snippet.javascript
<div className="card">
    <img src="photo.jpg" alt="Photo" />
    <label htmlFor="name">Nom :</label>
    <input type="text" id="name" tabIndex={1} />
    <button onClick={save}>Sauvegarder</button>
</div>

Exercice 2 : Affichage conditionnel

Créer un composant qui affiche :

Solution :

snippet.javascript
function ItemList({ loading, items }) {
    if (loading) {
        return <p>Chargement...</p>;
    }
 
    if (items.length === 0) {
        return <p>Aucun résultat</p>;
    }
 
    return (
        <ul>
            {items.map(item => (
                <li key={item.id}>{item.name}</li>
            ))}
        </ul>
    );
}

Points clés à retenir

  1. JSX n'est pas HTML : c'est du JavaScript transformé
  2. className au lieu de class, htmlFor au lieu de for
  3. Accolades {} pour insérer du JavaScript
  4. Ternaire ? : ou && pour les conditions
  5. map() pour les boucles, avec une key unique
  6. Fragments <></> pour retourner plusieurs éléments

← Chapitre précédent | Retour au module | Chapitre suivant : Composants →