:: Enseignements :: ESIPE :: E3INFO :: 2025-2026 :: Web et Géomatique ::
![[LOGO]](http://monge.univ-eiffel.fr/ens/resources/mlv.png) |
React et Appels asynchrones
|
Le but de ce TP est de réaliser une application de sélection de vol d'avions (flights)
et de trouver le vol ayant le prix le moins cher (Best Value).
La doc du Mozilla Developer Network
MDN
Dans un premier temps, nous avons besoin de deux choses, installer les bibliothèques de React
(
react et
react-dom) et récupérer l'outil
esbuild (un exécutable),
qui transforme les fichiers
.jsx en fichier
.js (et bundle les dépendances).
Pour récuperer
esbuild, nous allons utiliser
npm qui est le gestionnaire
de libraries JavaScript et qui permet aussi de récupérer des exécutables (ce qui est stupide en termes
de sécurité, mais c'est comme cela ...).
npm install --save-exact --save-dev esbuild
La commande
npm ci-dessus installe l'exécutable
esbuild dans le répertoire
./node_modules en locale donc pour exécuter
esbuild, on utilisera la commande
./node_modules/.bin/esbuild --version
Puis on va installer, toujours dans
./node_modules, les deux bibliothèques
react et
react-dom, toujours avec
npm
npm install --save-exact --save-dev react react-dom
On peut maintenant écrire un fichier JSX,
flight.jsx puis le transpiler en JavaScript avec
esbuild.
On utilise pour cela la commande
./node_modules/.bin/esbuild flight.jsx --bundle --outfile=flight.js
Il est important de faire attention à la qualité du code que vous allez rendre.
Avoir un code qui semble marcher, mais qui n'est pas maintenable, pas compréhensible ou
qui contient du code mort (qui ne sert à rien) sera fortement pénalisé.
Voilà une idée graphique de l'application que l'on veut réaliser
Et voilà l'arbre DOM que l'on souhaite obtenir.
Exercice 1 - Flights
L'API REST du serveur est définie comme ceci:
-
Obtenir tous les vols: GET /api/flights
Cet appel renvoi l'ensemble des vols au format JSON.
Pour simuler les possibles changements de prix, à chaque requête, un des vols a
son prix qui est changé de plus ou moins 10 dollars.
Vous pouvez tester en copiant dans votre navigateur http://localhost:8080/api/flights.
-
Supprimer un vol: DELETE /api/flights/id
Avec id, la valeur de l'id de l'évènement que l'on veut supprimer.
Cet appel renvoi un code 200 si cela s'est bien passé.
Pour démarrer, on va utiliser le fichier
flight.html suivant
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="icon" href="data:,">
<script src="flight.js" type="text/javascript"></script>
<style>
.app {
text-align: center;
margin: 20px;
}
button {
margin: 10px;
padding: 8px 16px;
cursor: pointer;
border-radius: 20px;
border: none;
background-color: #007bff;
color: white;
}
button:hover {
background-color: #0056b3;
}
table {
margin: 20px auto;
border-collapse: collapse;
width: 80%;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
th {
background-color: #dfdfdf;
cursor: pointer;
}
/* Display the sort order */
th.sort::after {
content: " ↓";
}
tr:nth-child(even) {
background-color: #f2f2f2;
}
/* Highlight the cheapest flight */
tr.highlight {
background-color: #ffff00af !important;
}
</style>
</head>
<body>
<div id="App"></div>
</body>
</html>
Et pour le fichier
flight.jsx suivant
import * as React from 'react';
import * as ReactDOM from 'react-dom/client';
function App() {
return <div className="app"></div>;
}
window.onload = () => {
const appDOM = document.getElementById("App");
const root = ReactDOM.createRoot(appDOM);
root.render(<App/>);
};
On utilisera de plus le serveur Java
JExpress.java
pour servir les fichiers
flight.html et
flight.js et l'API REST spécifique aux vols.
-
Utiliser esbuild pour réécrire le fichier JSX en fichier JS puis
lancer le serveur java JExpress.java dans le répertoire courant et
vérifier avec un navigateur que l'application s'affiche bien à l'adresse
http://localhost:8080/flight.html.
-
Pour le moment, on va écrire tout le code dans le même fichier flight.jsx
pour créer notre application.
Il ne faudra pas oublier après chaque modification de relancer esbuild
ou alors, vous pouvez utiliser l'option --watch.
Créer un composants FlightList qui permet d'afficher les vols (flight)
sous forme d'une table. Un vol est caractérisé par un aéroport de départ (from),
un aéroport d'arrivée (to), un temp de vol (duration) et un prix (price).
Pour récupérer les vols sur les vols, faite un appel asynchrone à l'API dans un useEffect.
Pour l'affichage de la durée de vol, le serveur renvoie la durée en minutes, vous utiliserez la fonction
suivante pour afficher la durée de vol en heure.
function toHour(minutes) {
return `${Math.floor(minutes / 60)}h ${minutes % 60}m`;
}
Pour les prix, ils sont en dollars.
Pour trouver la structure exacte, utiliser l'image de l'arbre DOM et de l'application ci-dessus.
Écrire le composant FlightList et visualiser que l'affichage est correcte.
Note: pour l'instant, on ne s'occupe pas des boutons.
Note2: penser que comme vous affichez une liste de vols, il ne faut pas oublier les clés pour React.
-
Ajouter un composant DeleteButton à la fin de chaque ligne, qui permet de supprimer
le vol correspondant.
Pour éviter trop d'aller-retour au serveur, le bouton "Delete" va demander la suppression au serveur
et si celle-ci est confirmée, supprimer la ligne dans l'affichage.
Attention, on vous demande de ne pas refaire un accès au serveur pour demander à nouveau la liste
des vols. Le changement au niveau de l'affichage est suffisant.
-
Ajouter un composant RefreshButton qui permet de remettre à jour la liste des vols
en redemandant au serveur la liste de vols. Le bouton doit être placé au-dessus de la table HTML.
-
On souhaite maintenant ajouter un composant CheapestButton qui met en sur-brillance (highlight)
le vol le moins cher parmi les vols affichés (il y a une classe pour cela dans le CSS).
La surbrillance doit disparaitre lorsque l'on demande un ré-affichage des vols avec le bouton "Refresh Flights"
car les prix peuvent avoir changé. Même chose si l'on demande la suppression d'un des vols.
Pour trouver le vol le moins cher, vous pouvez faire une boucle sur les vols ou (bonus) utiliser la méthode
reduce.
Ajouter le composant à l'application.
Note: vérifier que votre code ne plante pas si tous les vols ont été supprimée et
que l'on demande le vol le moins cher !
-
On souhaite maintenant découper le code en plusieurs fichiers.
- Un fichier api.js qui contient les fonctions qui font des fetchs
- Un fichier par gros composant
- Un fichier pour l'application
Utiliser export/import pour cela.
Expliquer quel est le problème de l'import * en JS.
Indiquer comment on supprime les import *.
Supprimer les import *.
-
On veut maintenant pouvoir trier l'affichage des vols en fonction de l'aéroport de départ (from).
Pour cela, ajouter un composant qui permet de trier les vols si l'on clique sur le titre "From" de la table.
Par défaut, aucun trie ne doit être fait, c'est uniquement lorsque l'utilisateur le demande que le trie
doit être fait.
Rappel: pour trier en JavaScript, on utilise une fonction de comparaison comme celle-ci
function compareFlight(f1, f2) {
if (f1.from < f2.from) {
return -1;
}
if (f1.from > f2.from) {
return 1;
}
return 0;
}
-
Vérifier que lors d'un trie si un vol est en surbrillance,
il doit rester en surbrillance (il sera juste déplacé par le trie).
Vérifier que si l'on rafraichit l'affichage en rechargeant les vols,
le trie ne doit pas être remis à zéro.
Faites les changements qui s'imposent.
-
Enfin, modifier votre code pour qu'il marche aussi pour trier selon les autres colonnes
(to, duration, price), sachant que l'on ne peut trier qu'une colonne à la fois.
Attention, si vous avez trop de duplication dans votre code, je ne vais pas être content,
essayer d'avoir un seul et même code qui fait les différents tris.
-
Enfin, ajouter une flèche (regarder le CSS), qui indique visuellement la colonne
qui est triée (s'il y en a une).
© Université de Marne-la-Vallée