JSX, Composants & TypeScript
Utilisez les flèches, cliquez ou glissez pour naviguer
1. Comprendre pourquoi React existe
Quel problème il résout
2. Créer un projet React + TypeScript
Avec Vite
3. Comprendre la syntaxe JSX
Différences avec HTML
4. Créer des composants fonctionnels
Avec props typées en TypeScript
Pourquoi React ?
DOM manuel = ingérable sur un vrai projet
Créer un projet avec Vite
npm create vite@latest -- --template react-ts
Anatomie d'un projet React
main.tsx, App.tsx, index.html
Introduction Ă JSX
Du HTML dans du JavaScript, avec des superpouvoirs
Premier composant avec props typées
Interface TypeScript
Synchroniser l'UI avec les données = cauchemar
// Exemple : Une liste de tâches
let todos = ["Acheter du lait"];
// Ajouter une tâche = mettre à jour le DOM manuellement
function addTodo(todo) {
todos.push(todo);
// 1. Créer l'élément
const li = document.createElement("li");
// 2. Définir le texte
li.textContent = todo;
// 3. Ajouter au DOM
document.getElementById("list").appendChild(li);
}
Imaginez avec 50 éléments, des suppressions, des filtres...
Le code devient vite ingérable!
Synchroniser l'UI avec les données automatiquement
Vous déclarez ce que l'UI doit afficher
React s'occupe de comment le mettre Ă jour
// Avec React : Déclaratif
function TodoList() {
const [todos, setTodos] = useState([...]);
return (
<ul>
{todos.map(t => <li>{t}</li>)}
</ul>
);
}
Impératif (DOM manuel)
"Crée un élément"
"Ajoute-lui du texte"
"Insère-le dans le DOM"
"Supprime l'ancien"
"Mets Ă jour le compteur"
Vous gérez TOUT
Déclaratif (React)
"L'UI affiche X"
"Quand X change, l'UI change"
React gère le reste
Comme l'event-sourcing : vous déclarez les événements, l'état se synchronise
Avec React : vous déclarez l'état, l'UI se synchronise
L'outil moderne pour démarrer rapidement
Build ultra-rapide + Hot Module Replacement
Support TypeScript natif
$ npm create vite@latest mon-app -- --template react-ts
# Crée un projet React + TypeScript
npm create vite@latest mon-app -- --template react-ts
cd mon-app
npm install
npm run dev
Démarre le serveur de développement
Le projet démarre sur http://localhost:5173
mon-app/
node_modules/
src/
main.tsx
App.tsx
App.css
index.html
package.json
tsconfig.json
vite.config.ts
.tsx
TypeScript + JSX
index.html
Point d'entrée HTML
package.json
Dépendances
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8" />
<title>Mon App</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
Le div#root est le point de montage
React injectera toute l'application ici
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import './index.css'
ReactDOM.createRoot(
document.getElementById('root')!
).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
main.tsx monte le composant App dans #root
C'est le seul fichier qui touche directement au DOM
function App() {
return (
<div className="App">
<h1>Bienvenue dans React!</h1>
<p>Mon premier composant</p>
</div>
);
}
export default App;
Un composant = une fonction qui retourne du JSX
C'est tout! Pas de classes, pas de magie
Mais avec des superpouvoirs
JSX n'est PAS du HTML
C'est du JavaScript qui ressemble Ă du HTML
// Ce JSX...
const element = <h1>Hello!</h1>;
// ...est compilé en JavaScript
const element = React.createElement('h1', null, 'Hello!');
Expressions JavaScript
const name = "Alice";
<p>Bonjour {name}!</p>
Les {} insèrent du JS
Attributs dynamiques
const url = "/home";
<a href={url}>...</a>
Pas de guillemets pour les {}
Appeler des fonctions
function formatName(user) { return user.name; }
<p>Bonjour {formatName(user)}!</p>
Des mots-clés différents!
HTML
<div class="container">
<label for="email">
JSX
<div className="container">
<label htmlFor="email">
class et for sont des mots-clés réservés en JavaScript!
Utilisez className et htmlFor Ă la place
CamelCase pour les attributs
onclick, onchange, onsubmit
tabindex, readonly
onClick, onChange, onSubmit
tabIndex, readOnly
Styles en objet
<div style={{ color: 'red', fontSize: 16 }}>
// Pas de chaîne CSS! Objet avec camelCase
Erreur!
return (
<h1>Titre</h1>
<p>Texte</p>
);
Deux éléments adjacents = erreur!
Correct
return (
<>
<h1>Titre</h1>
<p>Texte</p>
</>
);
Fragment <>...</>
Alternative : envelopper dans un div
Le Fragment n'ajoute pas d'élément au DOM
Qui retourne du JSX
C'est tout
Pas de classes, pas de magie, juste des fonctions
function Button() {
return <button>Cliquez-moi</button>;
}
export default Button;
Les props sont comme les paramètres d'une fonction
Elles permettent de personnaliser le composant
// Définition du composant
function Greeting(props) {
return <h1>Bonjour {props.name}!</h1>;
}
// Utilisation
<Greeting name="Alice" />
// Affiche: Bonjour Alice!
props = objet contenant tous les attributs passés
Plus lisible et explicite
// Avant
function Greeting(props) {
return <h1>Bonjour {props.name}!</h1>;
}
// Après (destructuring)
function Greeting({ name }) {
return <h1>Bonjour {name}!</h1>;
}
// Plusieurs props
function UserCard({ name, age, email }) { ... }
Une interface pour définir le contrat
interface GreetingProps {
name: string;
age?: number; // Optionnel
}
function Greeting({ name, age }: GreetingProps) {
return (
<div>
<h1>Bonjour {name}!</h1>
{age && <p>Vous avez {age} ans</p>}
</div>
);
}
interface UserCardProps {
name: string;
email: string;
avatar?: string;
isActive: boolean;
}
export default function UserCard({ name, email, avatar, isActive }: UserCardProps) {
return (
<div className="card">
{avatar && <img src={avatar} alt={name} />}
<h2>{name} {isActive && '(actif)'}</h2>
<a href={`mailto:${email}`}>{email}</a>
</div>
);
}
TypeScript vérifie les types à la compilation!
Erreur si on oublie une prop requise ou si le type est mauvais
import UserCard from './UserCard';
function App() {
return (
<>
<UserCard
name="Alice"
email="[email protected]"
isActive={true}
/>
<UserCard
name="Bob"
email="[email protected]"
avatar="/bob.jpg"
isActive={false}
/>
</>
);
}
Les props sans {} sont des chaînes
Les props avec {} sont des expressions JavaScript
1. Confondre JSX et HTML
className au lieu de class, htmlFor au lieu de for
2. Oublier l'élément racine unique
Utiliser <>...</> (Fragment) si nécessaire
3. Ne pas exporter le composant
Oublier export default ou export
// function Component() { ... }
export default function Component() { ... }
1
React synchronise l'UI avec les données
2
JSX = JavaScript qui ressemble Ă HTML
3
Composant = fonction qui retourne du JSX
4
Props = paramètres, typées avec interface
React simplifie la gestion de l'interface utilisateur
React
UI déclarative
Synchronise données/UI
JSX
HTML dans JS
Avec superpouvoirs
Composants
Fonctions + Props
Typés avec TypeScript
Prochaine étape : useState et la gestion d'état