TP2 - React Router - Partie 1
#
IntroductionA mesure que la complexité d'une application augmente, on commence à vouloir séparer notre contenu en écrans, afin de pouvoir exposer davantage de fonctionnalités, et reproduire un comportement familier pour l'utilisateur : nous parlons ici de navigation.
Bien que ce soit relativement aisé à accomplir seulement avec React, il y a de nombreux bénéfices à utiliser une librairie externe pour gérer la navigation de l'utilisateur.
Dans ce TP, nous allons pratiquer React Router. React Router est un paquet de la communauté, il n'est donc pas directement maintenu par Facebook. Cependant, c'est un projet mature, et présent dans l'écosystème React depuis longtemps. Par conséquent, il dispose de nombreuses fonctionnalités, est familier pour beaucoup de développeurs React, fiable, facile à comprendre, et très bien intégré aux fonctions de navigation des navigateurs. Vous pouvez trouver sa documentation ici.
#
Objet du TPDurant ce TP, vous allez créer une application (minimaliste) de critiques de vins. L'objectif est d'apprendre à se servir des fonctionnalités courantes d'un routeur front-end.
Comme d'habitude, vous pourrez trouver le résultat sur cette page.
#
Mise en place#
Create React AppCréez un nouveau projet avec Create React App à l'emplacement de votre choix :
npx create-react-app react-tp3
#
Projet GitlabCréez maintenant un projet react-tp3
sur le Gitlab de l'université.
danger
Pensez bien à décocher l'option proposant d'initialiser le repository !
Copiez l'adresse de ce nouveau repository à l'aide du bouton "Cloner avec SSH", puis exécutez les commandes suivantes dans le dossier de votre application crée à l'étape précédente en remplaçant <git-repo>
par cette dernière :
git remote add origin <git-repo>git push -u origin main
Vous devriez maintenant voir sur le README.md
de votre projet sur le Gitlab de l'université la documentation générée par Create React App.
#
Starter codeVous pouvez maintenant supprimer tout le contenu du dossier src
, et décompressez l'archive suivante à la place.
#
Séparer les composantsUne fois votre projet en place et le serveur de développement lancé, vous allez pouvoir observer à quoi ressemble la base de votre application.
Séparons donc quelques composants.
Review
#
Le composant Comme vous pouvez le constater, le premier bloc de notre application représente une critique de vin. Extrayez le morceau de code correspondant et placez le dans un nouveau composant nommé Review
, situé dans un nouveau fichier src/components/Review.jsx
.
Laissez ce morceau de code tel quel pour le moment, nous y reviendrons plus tard. Vous pouvez aussi l'enlever du composant App
pour le moment.
ReviewList
#
Le composant Si on continue de décomposer la structure de notre composant App
, le prochain composant à séparer est la liste des critiques de vin.
Extrayons cette liste dans un nouveau composant ReviewList
dans un fichier src/components/ReviewList.jsx
.
Modifiez ensuite ce composant de manière à afficher toutes les critiques présentes dans fichier src/api/db.json
.
Dans une application réelle, vous auriez probablement dû faire une requête AJAX pour aller chercher la liste des critiques, mais dans un souci de simplicité, vous pouvez ​importer​ ce fichier directement dans votre code.
Layout
#
Le reste de notre composant App
consiste maintenant en une barre de menu en haut de page ainsi qu'un footer en bas de page.
Ces éléments pourraient rester tels quels dans le composant App
, mais afin de le rendre plus lisible, nous allons les extraire dans un nouveau composant nommé Layout
, que vous placerez dans un fichier src/components/Layout.jsx
.
On veut extraire ces composants, mais laisser le composant ReviewList
dans le composant App
. Pour ce faire, notre composant Layout
doit pouvoir être utilisé de cette façon :
<Layout> <ReviewList /></Layout>
tip
Une prop spéciale nommée children
est passée au composant Layout
quand il est utilisé de cette manière... Servez vous en pour afficher ses éléments enfants...
Une fois ceci terminé, faites un commit avec le commentaire "Ex 1 : Splitting components" et poussez vers le serveur.
git add .git commit -m 'Ex 1 : Splitting components'git push
#
Afficher une critiqueEntrons dans le vif du sujet : nous souhaitons avoir plusieurs pages au sein de notre application, et notamment une page permettant d'afficher une seule et unique critique de vin.
Commençons par installer React Router :
npm install react-router-dom
note
Nous installons le paquet react-router-dom
et non react-router
, qui contient en plus de la base de React Router les utilitaires pour manipuler la navigation dans un navigateur web. Sachez qu'il existe aussi un paquet équivalent pour React Native (react-router-native
).
#
L'API HTML5 HistoryAvec HTML5 a été introduite l'API History : cette dernière permet d'interagir avec l'historique de navigation de l'utilisateur depuis Javascript.
Elle permet notamment de manipuler l'URL dans la barre d'adresse du navigateur, donnant à l'utilisateur la possibilité d'interagir avec comme il en a l'habitude : ajout de favoris, envoi d'URL etc, même dans le cadre d'une "single page app", comme celle que nous sommes en train de construire, pour laquelle le serveur (ici le serveur de développement) ne renvoie qu'un seul et même document.
C'est aussi grâce à l'utilisation de cette API par React Router que votre navigateur ne rafraîchira pas la page quand vous cliquerez sur un lien, en ajoutant une entrée à l'historique, ce qui a pour effet de modifier l'URL courante.
L'historique de navigation consiste en une suite d'URL :
http:​//my-awesome-app.com/http:​//my-awesome-app.com/loginhttp:​//my-awesome-app.com/dashboardhttp:​//my-awesome-app.com/user/5
- Si l'utilisateur clique sur le bouton "Précédent" de son navigateur à l'adresse
/user/5​
, il reviendra à l'adresse/dashboard​
. - Si à partir de cette adresse, il clique sur le bouton "Suivant", il reviendra à son point de départ.
- Cependant, si il clique sur un autre lien, le reste de l'historique sera remplacé.
Vous connaissez très certainement ces principes simples, mais c'est exactement ce à quoi donne accès cette API.
React Router propose une surcouche sur cette API, permettant son bon fonctionnement dans différents environnements.
#
Choisir son routeurLe paquet NPM que vous avez installé à l'instant contient différents types de routeurs dont les cas d'utilisation diffèrent. En voici les plus communs :
HashRouter
Ce type de routeur utilise ​window.location.hash​
, c'est à dire le même type de lien qu'utilisent les ancres HTML. Ainsi l'adresse d'une page "Home" pourrait être : https://monsite.com#home​
.
Les adresses de ce type sont moins élégantes, et ce routeur ne supporte pas certaines fonctionnalités avancées de React Router, cependant il est très largement supporté par les navigateurs, même anciens, et fonctionne dans certains cas particuliers (comme dans la correction par exemple !)
MemoryRouter
Ce routeur stocke et gère la navigation de l'utilisateur exclusivement en mémoire, et ne modifie donc pas l'URL. Il peut être utile lors de tests, ou encore dans un environnement externe à un navigateur (Electron...).
BrowserRouter
C'est le routeur que nous allons utiliser. Ce routeur est basé sur l'​API history HTML5​ et permet de modifier l'adresse affichée dans la barre de votre navigateur, ainsi que l'historique des adresses parcourues. Pour une application web, ce type de routeur est idéal, tant que vous n’avez pas à supporter des ​navigateurs plus anciens ou exotiques​, ou autre besoin très spécifique.
Le routeur doit être placé plus haut dans la hiérarchie des éléments que ceux qui utiliseront les fonctionnalités de navigation. Dans notre cas, placez cet élément au plus haut niveau de notre application :
const App = () => { return <BrowserRouter> {/* ... */} </BrowserRouter>}
#
Ajouter des routesReact Router expose deux composants Routes
et Route
qui servent à déclarer les routes possibles pour notre application, ainsi que l'élément à afficher quand l'utilisateur arrive sur cette route.
Voici un exemple :
<Routes> <Route path="hello" element={<Hello />} /> <Route path="world" element={<World />} /><Routes>
Dans cet exemple, quand l'utilisateur arrivera Ă l'adresse /hello
de l'application, il se verra afficher le composant Hello
à l'endroit ou se trouve cet élément Route
.
note
Les éléments Route
doivent toujours être les enfants d'un élément Routes
.
Essayez d'afficher le composant Review
quand l'utilisateur arrive sur le chemin /view
. Testez en entrant l'adresse dans la barre d'adresse de votre navigateur.
Modifiez ensuite le lien "Random" du menu pour pointer sur cette page. Que remarquez vous lorsque vous cliquez dessus ?
Une fois ceci terminé, faites un commit avec le commentaire "Ex 2 : First routes" et poussez vers le serveur.
git add .git commit -m 'Ex 2 : First routes'git push
#
Les liensAutre composant particulièrement utile,
sert, sans grande surprise, Ă afficher un lien vers une autre page.Il s'utilise de la sorte :
<nav> <ul> <li> <Link to="/">Home</Link> </li> <li> <Link to="page1">Page 1</Link> </li> <li> <Link to="page2">Page 2</Link> </li> </ul></nav>
Remplacez l'élément a
dans le menu "Random" par un élément Link
. Comme vous pouvez l'observer en cliquant dessus, contrairement à l'élément a
, le composant Link
navigue vers une nouvelle adresse sans recharger la page.
#
Index et page par défautLe composant Route
peut recevoir Ă la place d'une prop path
une prop booléenne index
, précisant que cette route se situe à la racine de l'adresse.
Ajoutez une route affichant le composant ReviewList
comme index de notre application.
Essayez d'aller à l'adresse suivante : http://localhost:3000/qwerty (en supposant que votre serveur de développement est sur le port 3000 bien sûr...). Pas très pratique...
Créez un composant NotFound
dans un fichier src/components/NotFound.jsx
. Il devra juste afficher un petit message d'erreur et un bouton permettant de revenir Ă l'accueil.
Pour afficher ce composant, créez une nouvelle route ayant pour prop path
la chaîne de caractères *
(wildcard). Cette route sera systématiquement affichée si aucune autre route déclarée avant n'est affichée.
Une fois ceci terminé, faites un commit avec le commentaire "Ex 4 : Links, index and fallback" et poussez vers le serveur.
git add .git commit -m 'Ex 4 : Links, index and fallback'git push
#
Les paramètres de routeMaintenant que nous savons afficher quelques routes statiques, notre application aurait bien besoin de quelques routes dynamiques pour pouvoir afficher le contenu d'une critique en fonction de l'URL.
Modifiez votre composant ReviewList
pour que chaque "carte" de critique soit un lien qui emmène l'utilisateur vers une page /view/<review.slug>
.
Il nous faut maintenant préciser à React Router que notre route peut prendre un paramètre. Il faudra ensuite récupérer ce paramètre dans une variable afin de trouver la critique associée au "slug" passé dans l'URL.
Pour vous inspirer, voici deux exemples : une route avec un paramètre nommé name
et un composant qui récupère ce paramètre et l'affiche dans un paragraphe.
<Route path="names/:name" element={<DisplayName />}>
import { useParams } from 'react-router-dom'
const DisplayName = () => { const params = useParams() return <p>{params.name}</p>}
#
Critique aléatoireComme vous pouvez le remarquer en cliquant sur le lien "Random" dans le menu, ce dernier ne fonctionne plus correctement...
Modifiez votre composant Review
pour lui faire afficher une critique aléatoire quand il reçoit la chaîne de caractères "random" comme paramètre.
tip
Il existe une méthode Math.random()
qui retourne un chiffre aléatoire entre zéro et un...
Une fois ceci terminé, faites un commit avec le commentaire "Ex 5 : Review display and random reviews" et poussez vers le serveur.
git add .git commit -m 'Ex 5 : Review display and random reviews'git push
Félicitations d'en être arrivés jusqu'ici, notre petite application de critique de vins fonctionne ! Nous allons y ajouter davantage de fonctionnalités lors de la seconde partie de ce TP.