0% ont trouvé ce document utile (0 vote)
0 vues19 pages

Dev Web Client Riche-Module4-TP4 - Détails

Le document traite du routage côté client, de la consommation d'API REST et de l'utilisation des WebSockets pour créer des applications web modernes. Il explique comment gérer les états de chargement, de succès et d'erreur lors des requêtes API, ainsi que l'importance de la navigation fluide et des notifications en temps réel. Enfin, il propose un exercice pratique pour appliquer ces concepts à une application de liste de contacts.

Transféré par

fastmachbat
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
0 vues19 pages

Dev Web Client Riche-Module4-TP4 - Détails

Le document traite du routage côté client, de la consommation d'API REST et de l'utilisation des WebSockets pour créer des applications web modernes. Il explique comment gérer les états de chargement, de succès et d'erreur lors des requêtes API, ainsi que l'importance de la navigation fluide et des notifications en temps réel. Enfin, il propose un exercice pratique pour appliquer ces concepts à une application de liste de contacts.

Transféré par

fastmachbat
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

1.

Routage Client : L'épine dorsale de l'UX

Le routage côté client permet de changer de vue sans recharger la page entière, créant
une expérience de type "Application Native".

Concepts Clés

• Gestion des URLs : Mapper une URL (ex: /produits/12) à un composant


spécifique.
• Paramètres de route : Extraire des données variables de l'URL pour afficher du
contenu dynamique.
• Gardes de navigation (Guards) : Contrôler l'accès (ex: rediriger vers /login si
l'utilisateur n'est pas connecté).

Exemple (Logique React Router / Vue Router) :

JavaScript
// Définition d'une route avec paramètre
{ path: '/user/:id', component: UserProfile }

// Récupération du paramètre dans le composant


const { id } = useParams(); // Hook pour extraire l'ID

2. Consommation d'API REST : Connecter les données

Une application moderne ne vit pas en vase clos ; elle communique avec un serveur
(Back-end) via des requêtes HTTP.

Fetch vs Axios

Caractéristique fetch (Natif) Axios (Bibliothèque)


Installation Rien à installer npm install axios
JSON Manuel ([Link]()) Automatique
Intercepteurs Non Oui (pratique pour les tokens)
Compatibilité Moderne (ES6+) Très large
Exporter vers Sheets

Gestion du cycle de vie d'une requête

Pour une expérience utilisateur propre, vous devez gérer trois états :

1. Chargement (isLoading) : Afficher un spinner.


2. Succès (data) : Afficher les données reçues.
3. Erreur (error) : Message clair en cas de problème serveur ou réseau.

3. WebSockets : Le Temps Réel (Introduction)

Contrairement au HTTP (Requête -> Réponse), le WebSocket ouvre un "tube"


bidirectionnel entre le client et le serveur.
Pourquoi l'utiliser ?

• Chat en direct : Recevoir un message sans rafraîchir.


• Notifications : Alertes instantanées.
• Tableaux de bord : Mise à jour de prix ou de stats en temps réel.

Fonctionnement simplifié

1. Handshake : Le client demande à passer de HTTP à WebSocket.


2. Connexion ouverte : Les deux parties peuvent envoyer des messages à tout
moment.
3. Événements : On écoute des événements (ex: [Link]('message', ...)).

Résumé Technique

Sujet Outil standard Objectif principal


Navigation React Router / Vue Router Fluidité et URLs propres
Échanges REST Axios / Fetch API Persistance des données
Temps Réel [Link] / Native WebSockets Interactivité instantanée
Exporter vers Sheets

Exercice pratique suggéré :

Pour valider ce module, je vous conseille de créer une petite "Liste de Contacts" :

1. Une page liste (/contacts) qui récupère des données via une API (type
JSONPlaceholder).
2. Une page détail (/contacts/:id) accessible au clic.
3. Un petit badge de notification simulé par un WebSocket qui s'incrémente quand
un "nouveau contact" est ajouté sur le serveur.
Exemple de code complet pour l'une de ces parties (par exemple, la
consommation d'API avec gestion d'erreurs)

La consommation d'API est le cœur battant de toute application fonctionnelle.

Pour cet exemple, nous allons utiliser React avec Axios (plus robuste que fetch pour la
gestion des erreurs) et l'API gratuite JSONPlaceholder pour simuler un backend réel.

Architecture de la requête
Avant de coder, visualisons le flux de données. Une requête asynchrone doit
impérativement gérer les trois états critiques pour ne pas laisser l'utilisateur dans le
noir.

Exemple de Code : Composant UserList


Ce composant récupère une liste d'utilisateurs, gère le délai de chargement et affiche
une alerte si le serveur ne répond pas.

JavaScript
import React, { useState, useEffect } from 'react';
import axios from 'axios';

const UserList = () => {


// 1. États pour gérer le cycle de vie de la donnée
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);

// 2. Fonction de récupération des données


const fetchUsers = async () => {
try {
setLoading(true); // Début du chargement
const response = await [Link]('[Link]

// Simulation d'un délai réseau pour voir le spinner


setTimeout(() => {
setUsers([Link]);
setLoading(false);
}, 1000);

} catch (err) {
// 3. Gestion fine des erreurs
setError("Impossible de récupérer les utilisateurs. Vérifiez votre connexion.");
setLoading(false);
[Link]("Détails de l'erreur:", [Link]);
}
};
// 4. Déclenchement au montage du composant
useEffect(() => {
fetchUsers();
}, []);

// --- RENDU CONDITIONNEL ---

// État : Chargement
if (loading) return <div className="spinner">Chargement des données...</div>;

// État : Erreur
if (error) return <div className="error-message"> {error}</div>;

// État : Succès (Affichage des données)


return (
<div className="user-container">
<h2>Liste des Utilisateurs</h2>
<ul>
{[Link](user => (
<li key={[Link]} className="user-card">
<strong>{[Link]}</strong> - {[Link]}
</li>
))}
</ul>
</div>
);
};

export default UserList;

Pourquoi cette structure est-elle "pro" ?


1. Le try...catch : C'est votre filet de sécurité. Sans lui, une erreur 404 ou 500 ferait
planter toute votre interface.
2. L'état loading : Indispensable pour l'UX. Un utilisateur qui clique et ne voit rien
pendant 2 secondes pensera que l'app est cassée.
3. Le useEffect avec tableau de dépendances vide [] : Cela garantit que l'appel API
ne se fait qu'une seule fois lors de l'affichage du composant, évitant ainsi des
boucles infinies de requêtes.
4. La séparation des responsabilités : Le rendu change dynamiquement selon l'état
de la variable error ou loading.
Maintenant que nous savons récupérer des données, on vas voir comment
transformer chaque nom d'utilisateur en un "Lien" cliquable vers une page de profil
détaillée en utilisant le Routage (Module 4.1):

C'est l'étape logique pour transformer une simple liste en une véritable application. Pour
cela, nous allons utiliser React Router, la bibliothèque de référence pour le routage.

L'idée est de passer d'une URL fixe (/users) à une URL dynamique (/users/1, /users/2,
etc.) et d'extraire cet identifiant pour afficher le bon profil.

1. Configuration des Routes ([Link])

D'abord, nous devons définir le "plan de circulation" de notre application.

JavaScript
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import UserList from './UserList';
import UserDetail from './UserDetail';

function App() {
return (
<Router>
<Routes>
{/* Route principale */}
<Route path="/" element={<UserList />} />

{/* Route dynamique avec le paramètre :id */}


<Route path="/user/:id" element={<UserDetail />} />
</Routes>
</Router>
);
}

2. Transformer la Liste en Liens ([Link])

On remplace la balise <li> simple par le composant <Link> de React Router. Cela permet
de changer l'URL sans recharger la page.

JavaScript
import { Link } from 'react-router-dom';

// ... à l'intérieur du map dans votre UserList :


<ul>
{[Link](user => (
<li key={[Link]} className="user-card">
{/* On crée un lien dynamique vers l'ID de l'utilisateur */}
<Link to={`/user/${[Link]}`} style={{ fontWeight: 'bold' }}>
{[Link]}
</Link>
<span> - {[Link]}</span>
</li>
))}
</ul>

3. Récupérer le paramètre dans la page de destination ([Link])

C'est ici qu'intervient le hook useParams. Il permet de "lire" l'ID présent dans l'URL pour
faire un nouvel appel API spécifique.

JavaScript
import React, { useState, useEffect } from 'react';
import { useParams, Link } from 'react-router-dom';
import axios from 'axios';

const UserDetail = () => {


const { id } = useParams(); // On récupère l'ID depuis l'URL
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);

useEffect(() => {
const fetchUser = async () => {
try {
// On appelle l'API pour UN SEUL utilisateur grâce à l'ID
const response = await
[Link](`[Link]
setUser([Link]);
setLoading(false);
} catch (err) {
[Link]("Erreur profil:", err);
}
};
fetchUser();
}, [id]); // On re-déclenche si l'ID change

if (loading) return <p>Chargement du profil...</p>;

return (
<div className="profile-card">
<Link to="/">← Retour à la liste</Link>
<h2>Profil de {[Link]}</h2>
<p><strong>Ville :</strong> {[Link]}</p>
<p><strong>Entreprise :</strong> {[Link]}</p>
<p><strong>Site web :</strong> {[Link]}</p>
</div>
);
};

Ce qu'il faut retenir (Le "Secret Sauce")

1. Le Symbole : : Dans la route /user/:id, le : indique que id est une variable.


2. Link vs <a> : On n'utilise jamais <a> en React pour la navigation interne, car cela
rafraîchirait toute la page (perte d'état). Link intercepte le clic pour changer juste
le composant.
3. Récupération de données ciblée : Au lieu de charger tous les détails dans la
liste, on ne charge que le strict nécessaire, puis on fait un appel spécifique sur la
page de détail. C'est plus performant.
Pour une dernière partie du module : une introduction aux WebSockets pour
ajouter une notification "Utilisateur en ligne":

Contrairement au protocole HTTP (où le client doit toujours demander pour recevoir),
les WebSockets permettent au serveur de "pousser" une information au client dès
qu'elle survient. C'est le mode Full-Duplex.

1. Le concept : HTTP vs WebSockets


Dans notre cas, nous voulons qu'une petite notification apparaisse dès qu'un nouvel
utilisateur se connecte, sans que l'utilisateur actuel n'ait à rafraîchir sa page.

2. Implémentation côté Client (React + [Link])


Pour cet exemple, nous utilisons la bibliothèque [Link], qui est le standard de
l'industrie pour simplifier l'usage des WebSockets.

Installation
Bash
npm install [Link]-client

Code du composant de Notification


Voici comment intégrer un écouteur d'événements temps réel dans votre application :

JavaScript
import React, { useState, useEffect } from 'react';
import { io } from '[Link]-client';

// Connexion au serveur de WebSocket (ex: un serveur [Link])


const socket = io("[Link]

const OnlineNotification = () => {


const [notification, setNotification] = useState(null);

useEffect(() => {
// 1. Écouter l'événement envoyé par le serveur
[Link]("user_connected", (data) => {
setNotification(`${[Link]} vient de se connecter !`);

// 2. Faire disparaître la notification après 5 secondes


setTimeout(() => setNotification(null), 5000);
});

// 3. Nettoyage : couper l'écouteur si le composant est détruit


return () => [Link]("user_connected");
}, []);
if (!notification) return null;

return (
<div className="toast-notification">
<span className="dot"></span> {notification}
</div>
);
};

export default OnlineNotification;

3. Ce qu'il se passe "sous le capot"

Étape Action

Handshake Le client dit au serveur : "Pouvons-nous parler en WebSocket ?"

Événement Le serveur envoie un message nommé "user_connected" avec un objet


{ name: "Alice" }.

Réception Le client reçoit ce message instantanément et met à jour son state.

Réactivité React détecte le changement d'état et affiche la bannière à l'écran.

Synthèse du Module 4
Félicitations ! Vous avez maintenant une vision complète du cycle de données d'une
application moderne :
1. Navigation : Fluidité entre les vues (React Router).
2. REST : Récupération de données persistantes (Axios).
3. WebSockets : Réactivité instantanée ([Link]).

Ce qu'il faut surveiller en production :


• Sécurité : Ne jamais oublier de passer le Token d'authentification (JWT) dans les
headers d'Axios ET lors de la connexion WebSocket.
• Performance : Toujours fermer les connexions WebSocket ([Link]()) pour
éviter les fuites de mémoire.
QCM de révision pour valider vos acquis sur l'ensemble de ce module 4 ?

Souhaitez-vous que je vous prépare un petit QCM de révision pour valider vos acquis
sur l'ensemble de ce module 4 ? oui
Gemini a dit
Excellent ! Voici un QCM de synthèse pour tester vos réflexes sur le Module 4.
Choisissez la ou les bonnes réponses pour chaque question.

QCM : Navigation et Échanges de Données

1. En routage client, à quoi sert le symbole : dans un chemin comme /produit/:id


?
• A. À indiquer que la route est privée et nécessite un mot de passe.
• B. À définir un paramètre dynamique que l'on pourra récupérer dans le
composant.
• C. À séparer le nom du composant du nom de l'URL.

2. Pourquoi préférer Link (de React Router) à une balise <a> classique ?
• A. Link est plus joli visuellement.
• B. <a> recharge toute la page, ce qui fait perdre l'état (state) de l'application.
• C. Link permet de se connecter plus rapidement à l'API.

3. Lors d'un appel API avec Axios, quel bloc de code capture les erreurs (ex: 404
ou 500) ?
• A. Le bloc .then()
• B. Le bloc finally {}
• C. Le bloc catch (error) {}

4. Quel est l'avantage principal d'un WebSocket par rapport au HTTP classique ?
• A. Il est plus facile à coder.
• B. Il permet au serveur d'envoyer des données au client sans que celui-ci ne les
demande.
• C. Il permet de télécharger des images plus lourdes.

5. Dans un useEffect, pourquoi passer un tableau vide [] en deuxième argument lors


d'un fetch ?
• A. Pour vider les données précédentes avant de charger les nouvelles.
• B. Pour s'assurer que l'appel API ne s'exécute qu'une seule fois au montage du
composant.
• C. C'est une erreur de syntaxe, il ne faut rien mettre.
Petit défi bonus (Architecture)
Question : Si vous développez une application de Bourse en ligne (où les prix changent
chaque seconde), quelle technologie privilégieriez-vous pour l'affichage des prix ?
• Réponse : ________________

Corrigé du QCM : Navigation et Échanges de Données

1. En routage client, à quoi sert le symbole : ?


• Réponse : B. Il sert à définir un paramètre dynamique.
• Explication : Dans /user/:id, le :id est une variable. Si l'URL est /user/42, React
Router comprend que id = 42. On récupère cette valeur avec le hook useParams().

2. Pourquoi préférer Link à une balise <a> classique ?


• Réponse : B. <a> recharge toute la page, ce qui fait perdre l'état (state).
• Explication : Le composant Link intercepte le clic, change l'URL dans la barre
d'adresse et met à jour l'affichage sans jamais rafraîchir le navigateur. C'est ce
qu'on appelle la navigation "In-App".

3. Quel bloc de code capture les erreurs avec Axios ?


• Réponse : C. Le bloc catch (error) {}.
• Explication : Le try contient le code qui "essaie" de s'exécuter. Si le serveur
renvoie une erreur (404, 500) ou si le réseau est coupé, le code saute
immédiatement dans le catch.

4. Quel est l'avantage principal d'un WebSocket ?


• Réponse : B. Il permet au serveur d'envoyer des données sans que le client ne
les demande.
• Explication : C'est le mode "Push". Contrairement au HTTP où le client est à
l'initiative, ici le serveur peut dire "Hé, il y a un nouveau message !" dès qu'il
arrive.

5. Pourquoi passer un tableau vide [] dans useEffect ?


• Réponse : B. Pour que l'appel ne s'exécute qu'une seule fois au montage.
• Explication : Sans ce tableau, React exécuterait l'appel API à chaque fois que le
composant se met à jour (re-render), ce qui créerait une boucle infinie de requêtes
et ferait planter votre navigateur ou le serveur.

Réponse au Défi Bonus (Architecture)


Question : Quelle technologie pour une application de Bourse en ligne ? Réponse : Les
WebSockets.

Pourquoi ? Parce que le prix des actions change par millisecondes. Faire des requêtes
HTTP (fetch) toutes les secondes surchargerait le serveur inutilement. Avec un
WebSocket, le serveur "pousse" les nouveaux prix en flux continu (Streaming) dès qu'ils
changent.

Bilan du Module 4
Vous avez maintenant les bases solides pour :
1. Structurer une application multi-pages fluide.
2. Connecter votre front-end à n'importe quel service cloud ou base de données via
REST.
3. Anticiper les besoins d'interactivité instantanée avec les WebSockets.
Pour mettre en pratique ce Module 4, rien de tel qu'un projet concret. Voici l'énoncé de
votre projet "Fil Rouge" : Le Tableau de Bord des Missions Spatiales.

Ce projet vous obligera à manipuler le routage, les appels API réels et la logique de
notification.

Projet : "Galactic Dashboard"


L'objectif est de créer une interface qui liste les lancements de fusées, permet de voir les
détails d'une mission et reçoit des alertes "en direct".

Liste des Tâches (To-Do List)

1. Architecture & Navigation (Routage)


• [ ] Installer react-router-dom.
• [ ] Créer deux pages : [Link] (La liste) et [Link] (Le détail).
• [ ] Configurer une route dynamique : /mission/:id.
• [ ] Ajouter une barre de navigation simple avec un lien "Accueil".

2. Consommation d'API (REST)


• [ ] Utiliser l'API gratuite de SpaceX (Lien :
[Link]
• [ ] Dans [Link], récupérer les 10 derniers lancements avec axios.
• [ ] Gérer l'état Loading (afficher "Calcul de la trajectoire...") et l'état Error (si l'API
est hors ligne).
• [ ] Créer un lien <Link> sur chaque mission pour envoyer l'utilisateur vers son ID
spécifique.

3. Page de Détails (Paramètres de route)


• [ ] Dans [Link], récupérer l'ID avec useParams.
• [ ] Faire un nouvel appel API spécifique à cette mission (.../launches/{id}).
• [ ] Afficher le nom de la mission, la date, et une image (si disponible dans
[Link]).

4. Simulation Temps Réel (WebSockets)


• [ ] Créer un petit composant [Link] en haut de l'écran.
• [ ] Défi : Puisqu'un serveur WebSocket peut être complexe à configurer
immédiatement, simulez-le avec un setInterval dans un useEffect qui affiche une
notification "Nouveau lancement détecté !" de manière aléatoire toutes les 30
secondes.
Aide Mémoire Technique

Besoin Outil / Syntaxe

Changer de page <Link to="/mission/abc">Voir</Link>

Lire l'ID const { id } = useParams();

Appel API [Link](url).then(res => setData([Link]))

Effet de bord useEffect(() => { ... }, [id])

Votre défi personnel :


Essayez d'ajouter un bouton "Favoris" sur la page de détail. Ce bouton ne sauvegardera
rien en base de données pour l'instant (car nous n'avons pas de Back-end), mais il doit
changer de couleur quand on clique dessus.

Squelette" de code de départ (le fichier [Link] configuré) pour vous lancer plus vite
sur ce projet.

Ce squelette configure la structure de navigation (le "cerveau" de l'app) et intègre le


système de notifications globales.

Voici le fichier [Link] prêt à l'emploi. Assurez-vous d'avoir installé les dépendances
nécessaires au préalable : npm install react-router-dom axios

Le Squelette de Départ ([Link])


JavaScript
import React from 'react';
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';

// Import de vos futurs composants


import Home from './pages/Home';
import MissionDetail from './pages/MissionDetail';
import AlertSystem from './components/AlertSystem';

// Style minimaliste pour la démo


const navStyle = {
padding: '1rem',
background: '#1a1a2e',
color: 'white',
display: 'flex',
gap: '20px'
};

function App() {
return (
<Router>
{/* 1. Système d'alerte global (toujours visible) */}
<AlertSystem />

{/* 2. Barre de Navigation */}


<nav style={navStyle}>
<h2 style={{ margin: 0 }}> SpaceX Tracker</h2>
<Link to="/" style={{ color: 'white', textDecoration: 'none' }}>Accueil</Link>
</nav>

{/* 3. Configuration des Routes */}


<div style={{ padding: '20px' }}>
<Routes>
{/* Route pour la liste des lancements */}
<Route path="/" element={<Home />} />

{/* Route dynamique pour le détail d'un lancement */}


<Route path="/mission/:id" element={<MissionDetail />} />

{/* Route 404 (Optionnel mais recommandé) */}


<Route path="*" element={<h2>404 - Mission perdue dans l'espace</h2>} />
</Routes>
</div>
</Router>
);
}

export default App;

Quelques conseils pour la suite :


1. Dans [Link] : Utilisez [Link]('[Link]
Pour ne pas saturer l'écran, vous pouvez utiliser .slice(0, 10) sur le tableau de
résultats pour n'afficher que les 10 plus récents.
2. Dans [Link] : N'oubliez pas le hook const { id } = useParams(); pour
savoir quelle mission l'utilisateur a cliquée.
3. Pour le CSS : Utilisez des Flexbox pour afficher vos missions sous forme de
"cartes" (Cards) élégantes.

Prochaine étape pour vous :


composant [Link] pour réussir votre premier appel API réel sur SpaceX

Le composant [Link] est le point d'entrée de vos données. C'est ici que nous allons
mettre en pratique la consommation d'API, la gestion des états de chargement et le
rendu de liste.

Voici un code propre et commenté pour votre page d'accueil.


Le composant [Link]
JavaScript
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import { Link } from 'react-router-dom';

const Home = () => {


// 1. Déclaration des états
const [missions, setMissions] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);

// 2. Appel à l'API SpaceX


useEffect(() => {
const fetchMissions = async () => {
try {
setLoading(true);
// On récupère tous les lancements
const response = await [Link]('[Link]

// On ne garde que les 10 derniers pour la clarté


setMissions([Link](-10).reverse());
setLoading(false);
} catch (err) {
setError("Erreur lors de la connexion à la base de SpaceX.");
setLoading(false);
}
};

fetchMissions();
}, []);

// 3. Gestion de l'affichage (Rendu conditionnel)


if (loading) return <div className="loader"> Analyse de la télémétrie en
cours...</div>;
if (error) return <div className="error">{error}</div>;

return (
<div>
<h1>Dernières Missions SpaceX</h1>
<div style={gridStyle}>
{[Link](mission => (
<div key={[Link]} style={cardStyle}>
<h3>{[Link]}</h3>
<p>Date : {new Date(mission.date_utc).toLocaleDateString()}</p>
{/* 4. Lien vers le détail avec l'ID dynamique */}
<Link to={`/mission/${[Link]}`} style={buttonStyle}>
Voir les détails
</Link>
</div>
))}
</div>
</div>
);
};

// Petits styles rapides pour la mise en page


const gridStyle = {
display: 'grid',
gridTemplateColumns: 'repeat(auto-fill, minmax(250px, 1fr))',
gap: '20px'
};

const cardStyle = {
border: '1px solid #ccc',
padding: '15px',
borderRadius: '8px',
backgroundColor: '#f9f9f9'
};

const buttonStyle = {
display: 'inline-block',
marginTop: '10px',
padding: '8px 12px',
backgroundColor: '#005288',
color: 'white',
textDecoration: 'none',
borderRadius: '4px'
};

export default Home;

Décryptage des points clés


1. [Link](-10).reverse() : L'API renvoie des centaines de lancements. En
utilisant slice(-10), on prend les 10 derniers du tableau, et reverse() permet
d'afficher le plus récent en premier.
2. new Date(...).toLocaleDateString() : Les dates d'API sont souvent brutes (format
ISO). Il est crucial de les formater pour l'utilisateur final.
3. Le Mapping : Chaque objet mission possède un id unique. On s'en sert pour la
key (performance React) et pour construire l'URL du lien.

Prochaine étape :
composant [Link] pour extraire cet ID et afficher les spécificités de la
fusée

Le composant [Link] va démontrer toute la puissance du routage dynamique


: il va "écouter" l'URL, capturer l'identifiant unique, et aller chercher les détails
spécifiques à cette mission précise.
Le composant [Link]
Voici comment récupérer le paramètre et afficher les données détaillées (incluant l'image
du patch de la mission).

JavaScript
import React, { useState, useEffect } from 'react';
import { useParams, Link } from 'react-router-dom';
import axios from 'axios';

const MissionDetail = () => {


// 1. Extraction de l'ID depuis l'URL
const { id } = useParams();

const [mission, setMission] = useState(null);


const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);

useEffect(() => {
const fetchMissionDetails = async () => {
try {
setLoading(true);
// Appel spécifique pour UNE mission via son ID
const response = await
[Link](`[Link]
setMission([Link]);
setLoading(false);
} catch (err) {
setError("Impossible de charger les détails de cette mission.");
setLoading(false);
}
};

fetchMissionDetails();
}, [id]); // On surveille 'id' : si l'utilisateur change d'URL, on recharge !

if (loading) return <h2> Récupération des données télémétriques...</h2>;


if (error) return <div style={{ color: 'red' }}>{error}</div>;

return (
<div style={containerStyle}>
<Link to="/" style={backLinkStyle}>← Retour aux lancements</Link>

<div style={detailCardStyle}>
{/* Affichage du patch de la mission */}
<img
src={[Link]}
alt={[Link]}
style={{ width: '150px', marginBottom: '20px' }}
/>

<h1>Mission : {[Link]}</h1>
<p><strong>Détails :</strong> {[Link] || "Aucune description disponible
pour cette mission."}</p>
<p><strong>Numéro de vol :</strong> {mission.flight_number}</p>
<p><strong>Réussite :</strong> {[Link] ? " Succès" : " Échec"}</p>

{[Link] && (
<a href={[Link]} target="_blank" rel="noreferrer"
style={buttonStyle}>
Lire l'article complet
</a>
)}
</div>
</div>
);
};

// --- STYLES ---


const containerStyle = { maxWidth: '800px', margin: '0 auto', padding: '20px' };
const backLinkStyle = { display: 'block', marginBottom: '20px', color: '#005288',
fontWeight: 'bold' };
const detailCardStyle = { padding: '30px', border: '1px solid #ddd', borderRadius: '12px',
textAlign: 'center', backgroundColor: '#fff' };
const buttonStyle = { display: 'inline-block', marginTop: '20px', padding: '10px 20px',
backgroundColor: '#005288', color: 'white', textDecoration: 'none', borderRadius: '5px'
};

export default MissionDetail;

Ce que nous venons d'implémenter :


1. useParams() : C'est le "détecteur" de React Router. Il transforme /mission/123 en
un objet { id: "123" }.
2. L'Appel API Ciblé : Au lieu de télécharger toutes les missions à nouveau, on
demande au serveur SpaceX uniquement la mission qui nous intéresse. C'est plus
léger pour le réseau.
3. L'Image Dynamique : Nous utilisons les données imbriquées
([Link]) pour personnaliser l'interface.
4. Le Tableau de Dépendances [id] : C'est une sécurité. Si l'utilisateur clique sur
une suggestion de mission alors qu'il est déjà sur une page de détail, useEffect
détectera que l'ID a changé et lancera une nouvelle requête.

Félicitations, Capitaine !
Vous avez maintenant une application fonctionnelle qui :
1. Navigue entre plusieurs vues (Routage).
2. Affiche une liste dynamique issue d'un serveur (REST / Axios).
3. Affiche une page de détail précise (URL Params).

Vous aimerez peut-être aussi