Comprenez le principe de SPA
Prenons notre machine à voyager dans le temps et retournons aux débuts du Web. 🤖
À cette époque, l'immense majorité des sites consistaient en un groupe de pages, envoyées par le serveur, qui s'affichaient en fonction de la navigation. Pour chaque interaction, telle que l'envoi d'un formulaire, la page entière devait être rechargée.
Mais au début des années 2000, le concept de Single Page Application (SPA) commence à émerger. Les idées principales derrière ce concept sont les suivantes :
Les utilisateurs ne chargent une page web qu'une seule fois (le fameux
index.html
).Au lieu de récupérer toute la page avec un call API, on les récupère de manière distincte, petite partie par petite partie, ce qui permet à l'utilisateur d'interagir de manière beaucoup plus dynamique.
L'utilisateur peut naviguer entre plusieurs pages, et JavaScript (et dans notre cas, React) gère l'affichage de nouvelles pages au sein du même domaine, sans qu'un rafraîchissement complet de la page soit nécessaire.

Mais… Est-ce que ça veut dire que les SPA sont nécessairement mieux ? Et donc que tous les nouveaux sites sont codés pour être des SPA ???
Eh bien, non. Toutes les applications ne sont pas nécessairement des SPA. Lorsque vous codez votre site en Single Page Application, il faut être conscient de certains inconvénients : notamment que vos utilisateurs doivent impérativement avoir JavaScript pour que votre site fonctionne, ou bien au niveau du Search Engine Optimisation (SEO, l'optimisation de l'indexation de votre site par les moteurs de recherche), qui est plus laborieux pour les Single Page Applications.
Les projets que nous créons avec Create React App ne peuvent pas encore être considérés comme des Single Page Applications : il leur manque une solution de routing.
Découvrez React Router
Contrairement aux frameworks comme Angular, React ne nous fournit pas directement une solution pour gérer les routes de notre application. Pas de panique, comme pour quasiment tout en React, l'écosystème a vite comblé ce besoin. Il existe donc plusieurs solutions de routing. Celle à laquelle nous allons nous intéresser dans ce cours est React Router (le nom est plutôt bien trouvé, n'est-ce pas ? 🙃).
Du routing ? Très bien, mais concrètement, ça veut dire quoi une route ?
Comme nous pouvons le voir dans la documentation React Router, une route permet d'afficher des composants de manière conditionnelle, si le path (chemin) de l'URL correspond au path de la route.
On lui passe en prop le path auquel la route correspond, et elle se charge d'afficher les children qui lui sont passés.
Cette bibliothèque, créée par React Training, met à votre disposition tous les outils nécessaires pour gérer la navigation dans votre application côté client.
Alors partons à la découverte de React Router. 🚀
Créez votre premier fichier de routing
Nous allons commencer par installer la bibliothèque avec yarn add react-router-dom
. Si vous voulez en apprendre davantage sur la configuration, n'hésitez pas à jeter un œil à la documentation de React Router.
React Router est maintenant prêt à être utilisé ! 🎉
Actuellement, nous n'avons qu'une seule fonctionnalité avec Home
. Créons dès maintenant un nouveau composant pour le questionnaire.
Pour cela, on crée un fichier Survey.jsx
dans pages
. Pour le moment, gardons un composant très simple :
function Survey() {
return (
Questionnaire 🧮
)
}
Votre mission, si vous l'acceptez, est de pouvoir naviguer entre la page d'accueil – Home – et le questionnaire – Survey. 🕵️♀️
Vous vous en doutez sûrement : nous allons utiliser React Router et ses composants Router et Route !
Commençons par le Router. Il doit être placé à la racine de notre arborescence de composants, et va permettre d'englober toutes les routes que nous allons définir.
On a donc dans le fichier index.jsx
à la racine de notre projet :
import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter as Router } from 'react-router-dom'
ReactDOM.render(
StrictMode
.
.StrictMode,
document.getElementById('root')
)
L'idée est maintenant de mettre dans notre router toutes les routes qui seront accessibles.

Créons donc une route pour la page d'accueil, et pour notre questionnaire.
import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter as Router } from 'react-router-dom'
ReactDOM.render(
StrictMode
.
path="/"
path="/survey"
.StrictMode
)
Yay ! Si vous allez sur l'URL http://localhost:3000/, on a bien la page d'accueil qui s'affiche. Mais, pour http://localhost:3000/survey… Ohoh ! Les deux s'affichent.. ! Pas de panique, il vous suffit d'ajouter la prop exact
dans votre route pour Home
:
exact path="/"
Et voilà ! Ça fonctionne bien comme prévu ! 🚀

Mais bon… Ce n'est pas vraiment pratique de devoir taper toutes nos URL à la main dans la barre du navigateur pour changer de page. 🙈
Naviguez avec les Link
Profitons-en pour créer notre header, avec les liens vers les différentes pages de notre application.
Dans notre dossier /components
, on crée donc un nouveau dossier /Header
avec un fichier index.jsx
à l'intérieur, ce qui nous donne /components/Header/index.jsx
:
import { Link } from 'react-router-dom'
function Header() {
return (
to="/"Accueil
to="/survey"Questionnaire
)
}
export default Header
Ici, j'utilise Link
, qui nous vient de React Router et se comporte comme une balise anchor
. Il est donc très important de l'utiliser lorsque vous souhaitez naviguer pour l'accessibilité de votre application (et non utiliser des redirections déclenchées par des onClick
).
Utilisons maintenant Header
dans index.jsx
à la racine de notre projet :
import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter as Router, Route } from 'react-router-dom'
import Home from './pages/Home'
import Survey from './pages/Survey'
import Header from './components/Header'
ReactDOM.render(
StrictMode
.
exact path="/"
path="/survey"
.StrictMode,
document.getElementById('root')
)
Vous avez maintenant la base de votre application avec navigation : félicitations à vous, vous avez fait du bon boulot. 🚀
Maintenant que nous avons vu comment mettre en place le routing, j'en profite pour vous montrer comment découper notre router quand nous avons beaucoup de routes à gérer – dans un projet de code plus important, par exemple. Alors suivez-moi dans le screencast ci-dessous !
Récupérez des paramètres dans vos URL
La navigation de notre application fonctionne bien !

Mais comment faire si vous voulez passer des paramètres ? Par exemple, lorsqu'on va faire le questionnaire, et que le numéro de chaque question sera récupéré depuis l'URL ?
Eh bien, bonne question ! Le router vous permet de récupérer des paramètres ; pour cela, il suffit d'écrire votre route comme ici dans le fichier index.jsx
à la racine de /src
:
path="/survey/:questionNumber"
Dans components/Header/index.jsx
, mettons donc un numéro de question à la suite :
function Header() {
return (
to="/"Accueil
to="/survey/42"Questionnaire
)
}
Allons maintenant récupérer ce paramètre dans survey/index.jsx
à l'aide du hook useParams
, mis à disposition par React Router :
import { useParams } from 'react-router-dom'
function Survey() {
const { questionNumber } = useParams()
return (
Questionnaire 🧮
Question {questionNumber}
)
}
Félicitations à vous ! Vous avez récupéré le numéro de votre question en paramètre. ☀️
Créez une route pour les attraper toutes : 404
Quelle chance, tout fonctionne comme on le souhaite ! Mais qu'est-ce qui se passe si je commence à taper n'importe quoi dans mon URL ? Par exemple, si j'essaie d'accéder au contenu de http://localhost:3000/coucouCommentCaVa ?
Notre header s'affiche, mais rien d'autre… Moi, j'aimerais signaler à l'utilisateur que rien n'existe à cette adresse. Eh bien, ça vous dit quelque chose, les pages d'erreur ? C'est ce que nous allons faire ici : afficher une page 404.
On commence par créer un simple composant Error
dans components/Error/index.jsx
:
function Error() {
return (
Oups 🙈 Cette page n'existe pas
)
}
export default Error
On retourne maintenant dans notre Router. Nous allons avoir besoin du Switch de React Router : Switch
nous permet d'afficher uniquement la première route dont le chemin correspond, et on ajoute une route à laquelle on ne passe pas de prop path
.
Dans notre router, on a donc :
ReactDOM.render(
StrictMode
.
exact path="/"
path="/survey/:questionNumber"
.StrictMode,
document.getElementById('root')
)
Testons dans notre navigateur :

Yes ! 💪
Exercez-vous
Vous avez la base de votre application, félicitations à vous. C'est maintenant le moment de voler de vos propres ailes.
Vous trouverez la base de l'exercice sur la branche P1C2-begin. Vos objectifs sont les suivants :
Créer une nouvelle page
Results
et l'ajouter au router.Créer une nouvelle page
Freelances
, l'ajouter au router, et créer un lien dans leHeader
.Dans
Survey.jsx
, coder un lienprécédent
et un liensuivant
qui permettent respectivement de passer à la question précédente et à la question suivante.Si la question actuelle est à 1, le lien "précédent" n'est pas activé.
Si la question est à 10, le lien "suivant" ne s'affiche pas. À la place, il y aura un lien "Résultats" qui redirigera vers la page "Results".
La solution se trouve sur P1C2-solution.
En résumé
Avec les single page applications (SPA), l'utilisateur a l'impression de naviguer sur différentes pages, mais il n'existe qu'une seule page HTML sur laquelle le contenu est greffé avec JavaScript.
React Router est une des bibliothèques qui permettent de transformer une app React en SPA.
Le Router, les Routes et Switch permettent de gérer l'affichage des différentes pages.
Il est possible de passer des paramètres dans une route et de les récupérer avec
useParams()
.En indiquant une route sans path à la fin du Switch, cela permet de capturer toutes les routes dont le path ne correspond à aucune route déclarée, et donc de créer une page 404.
Notre application contient maintenant les pages nécessaires pour la suite ! 🎉 Au prochain chapitre, nous allons sécuriser nos props avec les PropTypes. Alors, RdV au prochain chapitre !