---
title: "Chapitre 2 : JSX"
weight: 370
---

# Chapitre 2 : JSX

## Qu'est-ce que JSX ?

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

```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.

```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 :

```javascript
// HTML
<div class="container">

// JSX
<div className="container">
```

### htmlFor au lieu de for

```javascript
// HTML
<label for="email">

// JSX
<label htmlFor="email">
```

### Style en objet

```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

```javascript
// HTML
<button onclick="handleClick()">
<input tabindex="1">

// JSX
<button onClick={handleClick}>
<input tabIndex={1}>
```

### Fermeture obligatoire des balises

```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

```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

```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).

```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 :

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

### Opérateur &&

Pour afficher quelque chose ou rien :

```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

```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()` :

```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 :

```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

```php
// PHP
<?php foreach ($users as $user): ?>
    <li><?= $user['name'] ?></li>
<?php endforeach; ?>
```

```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 :

```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 :

```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 :**

```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 :

- "Chargement..." si `loading` est true
- "Aucun résultat" si `items` est vide
- La liste des items sinon

**Solution :**

```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](/training/module2-introduction-react/philosophie) | [Retour au module](/training/module2-introduction-react) | [Chapitre suivant : Composants ->](/training/module2-introduction-react/composants)
