Aller au contenu
Réussir mon BTS SIO

Tape une notion, une commande ou le nom d'une épreuve.

Par exemple

Chapitre 118 minIntermédiaire

C'est quoi React ? Créer un projet avec Vite

Par Josselyn C., prof de BTS SIO. Mis à jour le .

À la fin de ce chapitre, tu sauras

  • expliquer ce que React change par rapport à la manipulation du DOM à la main ;
  • distinguer une application monopage d'un site multipage ;
  • créer un projet React et TypeScript avec Vite, et en lire la structure ;
  • installer les outils de développement du navigateur pour React.

3 exercices corrigés1 schéma

React est une bibliothèque JavaScript qui sert à construire des interfaces utilisateur à partir de composants : des fonctions qui décrivent un morceau d'écran à partir de données. Quand les données changent, React met lui-même la page à jour. Ce chapitre explique ce que React change par rapport au JavaScript « à la main », ce qu'est une application monopage, puis crée le projet AppliFrais avec Vite et TypeScript.

Le problème : synchroniser les données et la page

Avec le JavaScript du cours JavaScript, tu modifies la page en manipulant le DOM : tu cherches un élément, tu changes son texte, tu ajoutes une ligne. Voici l'ajout d'un frais dans un tableau, écrit à la main :

js
// JavaScript sans bibliothèque : tu dis au navigateur COMMENT modifier la page
const corps = document.querySelector('#frais tbody');
const total = document.querySelector('#total');
let somme = 35.5;

function ajouterFrais(frais) {
  const ligne = document.createElement('tr');
  ligne.innerHTML = `<td>${frais.libelle}</td><td>${frais.montant} €</td>`;   // dangereux, voir plus bas
  corps.append(ligne);
  somme += frais.montant;
  total.textContent = `${somme} €`;   // ne pas oublier le total…
}

Ce code marche sur un écran. Sur une application de vingt écrans, il devient ingérable :

  • Chaque modification de données doit être répercutée partout à la main. Tu ajoutes un frais : il faut mettre à jour le tableau, le total, le compteur dans l'en-tête, le bouton « Clôturer » qui devient actif. Un oubli, et la page affiche des informations contradictoires.
  • L'état est éparpillé entre des variables JavaScript et le DOM lui-même. Pour savoir combien de frais il y a, tu comptes des <tr> ou tu fais confiance à une variable : laquelle a raison ?
  • Le code est fragile : renommer une classe CSS casse un querySelector ailleurs.
  • innerHTML avec une saisie de l'utilisateur ouvre une faille XSS : un libellé qui contient du HTML est interprété par le navigateur (la faille XSS).

La réponse de React : décrire le résultat

React inverse la logique. Tu ne dis plus comment modifier la page : tu décris à quoi elle doit ressembler pour des données, et React s'occupe des modifications. C'est la programmation déclarative, par opposition à la programmation impérative du code précédent.

tsx
// React : tu décris CE QUE la page doit afficher pour ces données
function TableauFrais({ frais }: { frais: Frais[] }) {
  const total = frais.reduce((somme, f) => somme + f.montant, 0);
  return (
    <table>
      <tbody>
        {frais.map((f) => (
          <tr key={f.id}><td>{f.libelle}</td><td>{f.montant} €</td></tr>
        ))}
      </tbody>
      <tfoot><tr><td>Total</td><td>{total} €</td></tr></tfoot>
    </table>
  );
}

Le total est calculé à partir de la liste à chaque affichage : il ne peut pas être faux. Quand la liste change, React rappelle la fonction, obtient la nouvelle description de l'écran, la compare à l'ancienne et ne touche dans le DOM qu'aux éléments qui ont changé. Et il insère f.libelle comme du texte : un libellé qui contient <script> s'affiche tel quel, sans s'exécuter.

ce que tu écrisce que fait React1. Un événementclic sur « Ajouter »,saisie dans un champ2. Mise à joursetFrais(nouvelle)l'état change3. RenduReact rappelle la fonctiondu composant4. Réconciliationcompare avec le renduprécédent5. Commitmodifie dans le DOMseulement ce qui changel'écran attendle prochainévénementTu ne touches jamais au DOM : tu changes l'état, React redessine.
Tu changes l'état, React recalcule l'écran et ne modifie que ce qui a changé

Ce mécanisme porte plusieurs noms qu'il faut savoir reconnaître :

TermeSens
Rendu (render)React appelle la fonction du composant pour obtenir la description de l'écran. Ce n'est pas encore le dessin à l'écran
DOM virtuelL'arbre d'objets JavaScript que renvoient les composants, la « description » de l'écran
RéconciliationLa comparaison entre l'ancien et le nouvel arbre, pour trouver les différences
CommitL'application des différences au vrai DOM du navigateur
État (state)Les données qu'un composant mémorise et qui, en changeant, déclenchent un nouveau rendu (chapitre 4)

Bibliothèque ou framework ?

React se présente comme une bibliothèque : il ne s'occupe que de l'interface. La navigation entre les pages, le chargement des données ou les formulaires complexes viennent d'autres bibliothèques que tu choisis : React Router (chapitre 10), TanStack Query (chapitre 9). Un framework comme Angular impose au contraire une structure complète et fournit tout.

Dans la pratique, on parle souvent de « framework front » pour React, Vue et Angular. Retiens la nuance pour l'oral : React seul est une bibliothèque d'interface ; des frameworks comme Next.js ou React Router en mode framework sont construits par-dessus.

ReactVueAngular
NatureBibliothèque d'interfaceFramework progressifFramework complet
Créé parMeta (Facebook), 2013Evan You, 2014Google, 2016 (successeur d'AngularJS)
Écriture des vuesJSX : du balisage dans le JavaScriptGabarits HTML avec directives (v-if, v-for)Gabarits HTML avec directives, TypeScript obligatoire
Ce qui est fourniComposants et état ; le reste se choisitComposants, routeur et gestion d'état officielsTout : routeur, formulaires, HTTP, injection de dépendances
MobileReact NativePas d'équivalent officielPas d'équivalent officiel

React est le plus répandu dans les offres d'emploi et de stage, et ses idées (composants, état, rendu déclaratif) se retrouvent dans les deux autres. Il sert aussi de base au développement mobile avec React Native : les composants, les props, l'état et les hooks de ce cours s'y écrivent de la même façon.

L'application monopage (SPA)

Un site PHP classique renvoie une page HTML complète à chaque clic : le serveur fabrique la page, le navigateur la remplace entièrement. Une application React est le plus souvent une application monopage (Single Page Application, SPA) :

  1. Au premier accès, le serveur envoie une page HTML presque vide et un fichier JavaScript.
  2. Ce JavaScript construit toute l'interface dans le navigateur.
  3. Ensuite, les données arrivent d'une API en JSON (cours API REST) et la navigation entre les « pages » se fait sans recharger.
Site multipage (PHP)Application monopage (React)
Qui fabrique le HTMLLe serveur, à chaque requêteLe navigateur, avec JavaScript
Ce que renvoie le serveur après le premier chargementDes pages HTMLDes données JSON (l'API)
NavigationRechargement complet de la pageChangement d'écran sans rechargement
Premier affichageRapideAttend le téléchargement du JavaScript
Référencement naturelSimplePlus délicat (le contenu n'est pas dans le HTML reçu)
Usage typiqueSite vitrine, blog, petite applicationApplication métier avec beaucoup d'interactions

AppliFrais est une application métier réservée à des utilisateurs connectés : le référencement ne compte pas, l'interactivité si. La SPA est le bon choix. Pour un site public qui doit être bien référencé, on ajoute du rendu côté serveur avec un framework comme Next.js ou React Router en mode framework : React fabrique alors le HTML sur le serveur. Ce n'est pas l'objet de ce cours.

Le fil rouge : le front d'AppliFrais

Tout le cours construit une seule application, le front web d'AppliFrais. Les visiteurs médicaux du laboratoire GSB y saisissent leurs frais : chaque mois, une fiche de frais regroupe leurs frais hors forfait (un repas, un parking, un taxi) ; ils la complètent tant qu'elle est en cours (CR), puis elle est clôturée (CL), validée par un comptable (VA) et mise en paiement (MP).

Le front ne parle jamais à la base de données : il appelle l'API REST d'AppliFrais, celle que tu construis dans le cours Node.js et Express. À la fin du cours, l'application sait :

  • connecter un utilisateur et protéger ses pages ;
  • afficher ses fiches, filtrées par état ;
  • afficher le détail d'une fiche, ajouter et supprimer des frais hors forfait ;
  • gérer le chargement, les erreurs et l'accessibilité ;
  • se tester automatiquement et se déployer.

Les outils et leurs versions en 2026

OutilVersion utiliséeRôle
Node.js24 LTSExécute les outils de développement (Vite, les tests)
React et React DOM19.3La bibliothèque d'interface
Vite8Serveur de développement et construction du projet
TypeScript7Le typage du code (introduit progressivement)
React Router8La navigation entre les écrans (chapitre 10)
TanStack Query5Le chargement et le cache des données (chapitre 9)
Vitest et Testing Library5 et 16Les tests (chapitre 13)

Créer le projet avec Vite

Vite est l'outil qui sert ton application pendant le développement (avec rechargement instantané quand tu enregistres un fichier) et qui la construit pour la production. Vérifie d'abord ta version de Node.js :

bash
node --version    # v24.x attendu (React Router 8 exige au moins Node.js 22.22)

Puis crée le projet avec le modèle React et TypeScript :

bash
npm create vite@latest appli-frais -- --template react-ts
cd appli-frais
npm install
npm run dev

La dernière commande affiche une adresse, http://localhost:5173. Ouvre-la : la page d'accueil de Vite s'affiche. Modifie un texte dans src/App.tsx et enregistre : la page se met à jour sans recharger. C'est le remplacement de module à chaud (Hot Module Replacement, HMR).

CommandeEffet
npm run devLance le serveur de développement sur le port 5173
npm run buildVérifie les types puis construit la version de production dans dist/ (chapitre 15)
npm run previewSert le contenu de dist/ pour le tester avant de le déployer
npm run lintAnalyse le code avec oxlint, le linter installé par le modèle

La structure du projet

text
appli-frais/
├── index.html            la seule page HTML, avec <div id="root"></div>
├── package.json          dépendances et scripts
├── vite.config.ts        configuration de Vite
├── tsconfig.json         configuration de TypeScript (et tsconfig.app.json, tsconfig.node.json)
├── public/               fichiers copiés tels quels (favicon…)
└── src/
    ├── main.tsx          point d'entrée : monte l'application dans #root
    ├── App.tsx           le composant racine
    └── index.css         les styles globaux

Le fichier index.html contient une <div id="root"> vide et charge src/main.tsx. Ce dernier monte l'application React dans cette div :

tsx
// src/main.tsx
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import App from './App.tsx';
import './index.css';

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <App />
  </StrictMode>,
);
  • createRoot crée la racine React dans l'élément #root ; render y affiche le composant App.
  • Le ! après getElementById(...) dit à TypeScript : « je sais que cet élément existe ». Sans lui, TypeScript signale que la fonction peut renvoyer null.
  • StrictMode n'affiche rien. En développement seulement, il exécute certaines fonctions deux fois pour révéler les bogues (chapitre 6). Il n'a aucun effet en production.

Remplace le contenu de src/App.tsx par le premier composant d'AppliFrais, et supprime src/App.css et le dossier src/assets dont tu n'as plus besoin :

tsx
// src/App.tsx
export default function App() {
  return (
    <main>
      <h1>AppliFrais</h1>
      <p>Bienvenue, Lucas. Ta fiche d'octobre 2026 est en cours de saisie.</p>
    </main>
  );
}

Pourquoi TypeScript dès le début

Le modèle react-ts crée des fichiers .tsx : du JSX (le balisage dans le JavaScript, chapitre 2) écrit en TypeScript. TypeScript est du JavaScript auquel on ajoute des types : il vérifie, avant l'exécution, que tu passes les bonnes données aux bonnes fonctions.

tsx
type Frais = { id: number; libelle: string; montant: number };

const taxi: Frais = { id: 60, libelle: 'Taxi', montant: '18,40' };
//                                               ~~~~~~~
// Erreur : le type 'string' n'est pas assignable au type 'number'.

Ton éditeur souligne l'erreur pendant que tu tapes, et npm run build refuse de construire le projet tant qu'elle existe. Sur une application React, où des données circulent de composant en composant, ce filet de sécurité évite une grande partie des bogues d'affichage (undefined à l'écran, montant concaténé au lieu d'être additionné).

Tu n'as pas besoin de connaître TypeScript pour commencer : la plupart des types sont déduits automatiquement. Ce cours introduit les annotations quand elles deviennent utiles : les types des props au chapitre 3, ceux de l'état au chapitre 4, ceux des événements et des formulaires au chapitre 8, ceux des données de l'API au chapitre 7.

Les outils du navigateur

Installe l'extension React Developer Tools (Chrome, Firefox, Edge). Elle ajoute deux onglets aux outils de développement (F12) :

  • Components : l'arbre de tes composants, avec leurs props et leur état, modifiables en direct ;
  • Profiler : ce qui a été rendu et combien de temps cela a pris.

Garde aussi l'onglet Console ouvert : React y écrit ses avertissements en clair (clé manquante dans une liste, hook mal appelé…). La moitié des blocages d'un débutant se résolvent en lisant ce qu'il y a dans la console.

Exercices

Exercice 1 sur 3 Impératif ou déclaratif Réussi À revoir

Classe chaque extrait : impératif ou déclaratif ?

  1. document.querySelector('#total').textContent = total + ' €';
  2. <p>Total : {total} €</p>
  3. liste.removeChild(liste.children[2]);
  4. {fiches.map((f) => <li key={f.id}>{f.mois}</li>)}
  5. Une requête SQL SELECT mois FROM fiche WHERE etat = 'CR'.
Voir la réponseMasquer la réponse de l'exercice 1
  1. Impératif : on dit au navigateur quelle opération faire sur quel élément.
  2. Déclaratif : on décrit ce que le paragraphe contient ; React fait la mise à jour.
  3. Impératif : on retire un nœud précis.
  4. Déclaratif : on décrit la liste à afficher pour le tableau fiches.
  5. Déclaratif aussi : SQL décrit le résultat voulu, pas la manière de parcourir la table. React applique la même idée à l'interface.

Tu avais trouvé ?

Exercice 2 sur 3 SPA ou site multipage ? Réussi À revoir

Pour chaque projet, dis si tu choisirais une application monopage React ou un site multipage rendu côté serveur, et pourquoi.

  1. Le site vitrine d'une boulangerie, qui doit apparaître dans Google.
  2. L'outil interne de suivi des tickets d'un service informatique, utilisé toute la journée par cinq techniciens connectés.
  3. Le blog d'actualité d'une mairie.
  4. Un tableau de bord de supervision qui se met à jour toutes les dix secondes.
Voir la réponseMasquer la réponse de l'exercice 2
  1. Site multipage (ou rendu côté serveur) : peu d'interactions, et le référencement est essentiel.
  2. SPA : application métier, utilisateurs connectés, beaucoup d'interactions, référencement inutile.
  3. Site multipage : du contenu à lire et à référencer.
  4. SPA : l'écran se met à jour en continu sans rechargement, à partir d'une API.

Tu avais trouvé ?

Exercice 3 sur 3 Lire le projet Réussi À revoir

  1. Quel fichier faut-il modifier pour changer le titre de l'onglet du navigateur ?
  2. Dans quel dossier se trouve la version construite pour la production, après npm run build ?
  3. Un camarade te conseille npx create-react-app appli-frais. Que lui réponds-tu ?
  4. Que fait StrictMode en production ?
Voir la réponseMasquer la réponse de l'exercice 3
  1. index.html, la balise <title>. (Le chapitre 11 montre comment changer le titre selon la page affichée.)
  2. dist/.
  3. Que create-react-app est déprécié depuis février 2025 et n'est plus maintenu : on crée une SPA avec Vite (npm create vite@latest appli-frais -- --template react-ts).
  4. Rien : ses vérifications (doubles appels, avertissements) n'ont lieu qu'en développement.

Tu avais trouvé ?

Chapitre terminé !

Fais les 3 exercices avant de passer à la suite : c'est en t'entraînant que tout se fixe.

chapitres
–
de série
–
du cours
–
Chapitre suivant : JSX et composants ReactRevoir le sommaire du cours