JSX (JavaScript XML) est une extension de syntaxe qui permet d'écrire du HTML dans 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.
// 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.
class est un mot réservé en JavaScript :
// HTML <div class="container"> // JSX <div className="container">
// HTML <label for="email"> // JSX <label htmlFor="email">
// 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}>
// HTML <button onclick="handleClick()"> <input tabindex="1"> // JSX <button onClick={handleClick}> <input tabIndex={1}>
// HTML <img src="photo.jpg"> <input type="text"> <br> // JSX - toujours fermer <img src="photo.jpg" /> <input type="text" /> <br />
Utilisez les accolades {} pour insérer du 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> );
function formatName(user) { return `${user.firstName} ${user.lastName}`; } const user = { firstName: 'Jean', lastName: 'Dupont' }; return <h1>Bonjour, {formatName(user)} !</h1>;
Dans les accolades, vous pouvez mettre des expressions (qui retournent une valeur), pas des statements (if, for, while).
// 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 !
Pour afficher une chose ou une autre :
function Greeting({ isLoggedIn }) { return ( <div> {isLoggedIn ? ( <p>Bienvenue !</p> ) : ( <p>Veuillez vous connecter</p> )} </div> ); }
Pour afficher quelque chose ou rien :
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 && ...}.
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>; }
Pour afficher une liste, utilisez map() :
function UserList({ users }) { return ( <ul> {users.map(user => ( <li key={user.id}> {user.name} </li> ))} </ul> ); }
Obligatoire pour les listes. Permet à React d'identifier chaque élément :
// 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 ! ))}
// PHP <?php foreach ($users as $user): ?> <li><?= $user['name'] ?></li> <?php endforeach; ?>
// React {users.map(user => ( <li key={user.id}>{user.name}</li> ))}
Un composant doit retourner un seul élément racine. Si vous ne voulez pas ajouter de <div> inutile, utilisez un Fragment :
// 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> ); }
Convertir ce HTML en JSX :
<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 :
<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>
Créer un composant qui affiche :
loading est trueitems est videSolution :
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> ); }
{} pour insérer du JavaScript? : ou && pour les conditions<></> pour retourner plusieurs éléments← Chapitre précédent | Retour au module | Chapitre suivant : Composants →