Découverte de React

JSX, Composants & TypeScript

Utilisez les flèches, cliquez ou glissez pour naviguer

Objectifs de la leçon

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

Plan du cours

1

Pourquoi React ?

DOM manuel = ingérable sur un vrai projet

2

Créer un projet avec Vite

npm create vite@latest -- --template react-ts

3

Anatomie d'un projet React

main.tsx, App.tsx, index.html

4

Introduction Ă  JSX

Du HTML dans du JavaScript, avec des superpouvoirs

5

Premier composant avec props typées

Interface TypeScript

Le problème : DOM manuel

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!

La Solution : React

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 vs Déclaratif

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

Créer un Projet avec Vite

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

Étapes de création

1

npm create vite@latest mon-app -- --template react-ts

2

cd mon-app

3

npm install

4

npm run dev

Démarre le serveur de développement

Le projet démarre sur http://localhost:5173

Anatomie d'un Projet React

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

index.html - Le point d'entrée

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

main.tsx - Le bootstrap

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

App.tsx - Le composant racine

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

JSX : HTML dans JavaScript

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!');

Les superpouvoirs de JSX

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>

Piège : JSX != HTML

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

Autres différences importantes

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

Piège : Un seul élément racine

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

Un Composant = Une Fonction

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 : Paramètres du composant

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

Destructuring des props

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 }) { ... }

Typer les Props avec TypeScript

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>

);

}

Exemple complet : Carte utilisateur

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

Utiliser le composant

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

Pièges Courants

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() { ... }

Points Clés à Retenir

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

Résumé

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