Je suis vraiment ravi de partager avec vous aujourd'hui certaines techniques avancées de React Router . React Router est un outil incroyable qui nous permet de créer une navigation dynamique et fluide dans nos applications React .
Bien qu'il soit couramment utilisé pour les besoins de routage de base, il existe des techniques moins connues qui peuvent élever vos capacités de routage à un tout autre niveau.
Aujourd'hui, je vais partager quelques-uns de mes favoris que j'ai découverts au fil du temps.
useNavigate
et useLocation
.
Lorsque vous aurez fini de lire cet article, vous maîtriserez parfaitement ces techniques avancées de React Router et vous vous sentirez en confiance pour les appliquer dans vos propres projets.
Alors, plongeons-nous dans le vif du sujet et améliorons ensemble nos compétences en matière de routage !
Es-tu prêt? Commençons!
Lorsque vous travaillez sur des projets plus importants, il est essentiel de prendre soin des itinéraires introuvables. Nous appelons souvent ces routes des routes 404 car elles renvoient le code d'état HTTP 404 lorsqu'un document n'est pas trouvé sur le serveur.
Au fait, si vous aimez les chats, vous aimerez peut-être consulter http.cat .
Passons maintenant à la création d'une route spéciale qui sera déclenchée chaque fois qu'aucune des autres routes ne correspond à l'URL actuelle dans le navigateur.
import {BrowserRouter, Routes, Route} from "react-router-dom"; function App() { return <BrowserRouter> <Routes> <Route path="/" element={<p>Landing page</p>}></Route> <Route path="/products" element={<p>Products page</p>}></Route> <Route path="*" element={<p>404 page</p>}></Route> </Routes> </BrowserRouter> }
Lors de l'accès à la page principale /
, les utilisateurs seront dirigés vers la page d'accueil. Naviguer vers la page /products
les mènera à la page Produits. Cependant, si vous accédez à d'autres liens qui ne correspondent pas à un itinéraire spécifique, la page 404 s'affichera.
La raison de ce comportement est l'implémentation d'un <Route>
spécialisé pour la page 404, où la propriété path est définie sur *
. Cette configuration garantit que React Router utilisera exclusivement cette route lorsqu'aucune autre route ne peut être mise en correspondance. L'emplacement spécifique de l'itinéraire 404 est sans conséquence et peut être positionné n'importe où dans la section <Routes>...</Routes>
, en tant que partie intégrante de celle-ci.
Une autre façon pour les applications d'utiliser les itinéraires de manière pratique consiste à mettre en surbrillance la page actuellement active dans le menu.
Accueil - Ce lien amène l'utilisateur à la page principale /
.
À propos - Ce lien amène l'utilisateur à la page à propos /about
.
Avec React Router, il devient possible de mettre automatiquement en surbrillance le lien About
lorsque l'utilisateur est sur la route /about
. De même, vous pouvez mettre en surbrillance le lien Accueil lorsque l'utilisateur est sur la route /
. La meilleure partie est que vous pouvez y parvenir sans avoir besoin de conditions complexes.
import {NavLink} from "react-router-dom"; function getClassName({isActive}) { if (isActive) { return "active"; // CSS class } } function App() { return <ul> <li> <NavLink to="/" className={getClassName}>Home</NavLink> </li> <li> <NavLink to="/about" className={getClassName}>About</NavLink> </li> </ul> }
Le code que vous voyez ci-dessus a besoin de CSS pour faire fonctionner la classe active
. Nous pouvons donc l'améliorer en faisant en sorte que le lien de menu de la page actuellement active apparaisse en gras et se démarque.
.active { font-weight: bold; }
L'attribut className
de l'élément NavLink
a la possibilité d'accepter une fonction au lieu d'une simple chaîne. Lorsque vous décidez d'utiliser une fonction, un objet lui sera donné en tant que paramètre, et cet objet aura la propriété isActive
déjà définie dessus. Pour accéder facilement à cette propriété au sein de la fonction, nous utilisons la déstructuration en incluant {isActive}
dans le paramètre.
Ensuite, nous procédons à la vérification si isActive
contient une valeur de vérité. Si tel est le cas, nous renverrons le nom de la classe CSS active
.
Lorsque le chemin actuel dans React Router correspond à l'attribut to
du composant NavLink
, la fonction isActive
sera évaluée à une valeur booléenne.
En conséquence, React Router inclura de manière transparente la classe active
dans l'élément <NavLink />
correspondant, l'indiquant comme la route actuellement active.
Si vous préférez une approche plus courte, vous pouvez utiliser l'opérateur ternaire pour refactoriser le code mentionné ci-dessus. Cet opérateur permet de remplacer une instruction if/else en utilisant le format : condition ? truthy expression : falsy expression
.
Je n'utilise pas vraiment beaucoup l'opérateur ternaire car il peut souvent rendre le code moins lisible. Cependant, il est acceptable de l'utiliser dans ce cas.
function getClassName({isActive}) { if (isActive) { return "active"; } else { return ""; } }
function getClassName({isActive}) { return isActive ? "active" : ""; }
Vous devez simplement vous assurer que l'instruction return est placée en dehors de l'opérateur ternaire. Lorsque la condition isActive
est vraie, l'expression après ?
sera exécuté "active"
. Sinon, l'expression après :
sera exécutée ""
.
Maintenant, nous pouvons éliminer le besoin d'une définition de fonction distincte appelée getClassName
. Au lieu de cela, nous pouvons utiliser une fonction fléchée comme celle-ci : ({isActive}) => isActive ? "active" : ""
.
Si vous trouvez ce changement trop difficile à lire, vous pouvez continuer à utiliser une fonction distincte comme avant.
import {NavLink} from "react-router-dom"; function App() { return <ul> <li> <NavLink to="/" className={({isActive}) => isActive ? "active" : ""}>Home</NavLink> </li> <li> <NavLink to="/about" className={({isActive}) => isActive ? "active" : ""}>About</NavLink> </li> </ul> }
Oh boy, je peux pratiquement entendre vos pensées !
Sojin, vous avez rompu le principe DRY, n'est-ce pas ?
C'est juste un exemple. Pas besoin de s'énerver 😀
Vous avez peut-être déjà remarqué que j'utilise NavLink
au lieu de notre ami habituel, Link
. Mais ne vous inquiétez pas, laissez-moi vous expliquer pourquoi. Vous voyez, le composant <Link />
ne vous permet pas d'utiliser une définition de fonction pour la prop className
. Oui, cela peut être surprenant, mais c'est comme ça quand vous travaillez avec <Link />
.
Une erreur courante que j'ai vue est que les développeurs juniors de React essaient d'utiliser des définitions de fonction dans le prop className
d'un composant <Link />
, ce qui ne fonctionne tout simplement pas.
Si cela vous intéresse, je peux écrire un article sur ce sujet. Faites-le moi savoir dans les commentaires!
Dans certaines circonstances, vous devrez peut-être déplacer par programmation des pages dans votre application React. Par exemple, pour rediriger le visiteur vers une page spécifique, vous pouvez soumettre une demande et attendre la réponse.
/dashboard
.
Cela nécessite l'utilisation du crochet useNavigate()
, qui renvoie une fonction que vous pouvez utiliser pour rediriger par programme l'utilisateur vers une nouvelle route.
Regarde:
import React, {useEffect} from "react"; import {useNavigate} from "react-router-dom"; function HelpPage() { const navigate = useNavigate(); useEffect(() => { const isLoggedIn = window.localStorage.getItem("isLoggedIn"); if (!isLoggedIn) { navigate("/login"); } }, []); return <h2>Help page</h2>; }
Dans cet exemple, nous vérifions si le localStorage a une valeur affectée à la clé isLoggedIn
. Si ce n'est pas le cas, nous redirigerons l'utilisateur vers la page /login
à l'aide de la navigate("/login")
.
Pour que cela fonctionne, n'oubliez pas d'utiliser le hook useNavigate()
dans un composant imbriqué dans le composant <BrowserRouter />
. Sinon, il ne fonctionnera pas correctement.
Par exemple, l'exemple suivant ne fonctionnera pas :
import React from "react"; import {BrowserRouter, useNavigate} from "react-router-dom"; function App() { // ❌ This breaks because the component was not wrapped by BrowserRouter, but its children are. const history = useNavigate(); return <BrowserRouter> {/* ... */} </BrowserRouter>; }
Si vous essayez d'utiliser le hook useNavigate()
dans le composant App()
, vous risquez de rencontrer un petit problème. En effet, cela ne fonctionnera que si vous enveloppez le composant App()
avec <BrowserRouter />
.
Mais ne vous inquiétez pas !
La bonne nouvelle est que tous les composants enfants dans App seront automatiquement enveloppés par <BrowserRouter />
, vous pouvez donc utiliser useNavigate()
dans ces composants enfants sans aucun problème.
Cependant, si vous avez vraiment besoin d'utiliser useNavigate()
dans le composant <App />
lui-même, il existe une solution simple. Il vous suffit de créer un composant parent qui encapsule <App />
et assurez-vous de déplacer le <BrowserRouter />
à l'intérieur de ce composant parent. Une fois que vous avez fait cela, vous serez prêt à partir et pourrez utiliser useNavigate()
dans le composant <App />
à votre guise 💗
Lorsqu'il s'agit de rendre votre site Web accessible, il est important de prêter attention à la façon dont vos liens sont structurés. Pour garantir cela, il est recommandé d'utiliser des éléments <Link />
au lieu d'autres méthodes.
Pourquoi?
Eh bien, ces éléments s'afficheront automatiquement sous la forme de balises <a>
, connues pour leurs fonctionnalités d'accessibilité .
Maintenant, voici une astuce conviviale : évitez de remplacer vos éléments <Link />
normaux par la méthode .push()
fournie par useNavigate()
. Cette méthode ne doit être utilisée que dans les cas où l'utilisation d'un élément <Link />
n'est pas possible.
En règle générale, c'est lorsque vous devez rediriger les utilisateurs par programme en fonction d'une certaine logique, comme le résultat d'une opération fetch()
.
Et si vous vouliez exécuter un morceau de code chaque fois que React Router vous amène à une nouvelle adresse ?
Vous pouvez accomplir cela facilement à l'aide du hook useLocation
. Mais avant de plonger dans les détails, explorons quelques scénarios où cela peut être utile. L'un des cas d'utilisation les plus courants consiste à envoyer un événement de consultation de page à votre service d'analyse, comme Google Analytics.
Cependant, il convient de mentionner que Google Analytics 4 s'en charge désormais automatiquement, vous n'avez donc pas nécessairement à l'implémenter vous-même.
Néanmoins, en savoir plus sur le crochet useLocation
est toujours utile, car vous pourriez lui trouver d'autres objectifs. Par exemple, vous pouvez l'utiliser pour vous intégrer à d'autres bibliothèques et services d'analyse, ou pour exécuter des actions spécifiques en fonction des itinéraires visités.
Les possibilités sont infinies!
Le crochet useLocation
est super pratique car il vous donne des informations sur la route actuellement utilisée.
Voici un guide convivial sur la façon d'utiliser le crochet useLocation :
import {BrowserRouter, Routes, Route, useLocation} from "react-router-dom"; import {createRoot} from "react-dom/client"; function App() { const location = useLocation(); console.log(location.pathname); return <Routes> {/* routes here... */} </Routes> } createRoot(document.querySelector("#react-root")).render(<BrowserRouter><App /></BrowserRouter>);
Maintenant, vous pouvez accéder aux informations d'itinéraire via la variable d'emplacement. C'est un objet qui contient le pathname
actuel.
Pour savoir quel itinéraire l'utilisateur parcourt actuellement, utilisez simplement location.pathname
. Cela vous donnera quelque chose comme /
, /about
ou tout autre itinéraire que vous avez configuré.
N'oubliez pas que, tout comme avec le crochet useNavigate
, il est important que votre code s'exécute dans un composant enveloppé par <BrowserRouter />
. Sinon, le crochet useLocation
ne fera pas sa magie.
Lorsque l'emplacement change, vous pouvez utiliser le hook useLocation
pour accéder au chemin d'URL actuel dans React Router. En enveloppant votre code avec un hook useEffect
et en définissant la dépendance sur location
, vous pouvez exécuter un morceau de code spécifique chaque fois qu'il y a une navigation vers une nouvelle URL.
import React, {useEffect} from "react"; import {BrowserRouter, Routes, Route, useLocation} from "react-router-dom"; import {createRoot} from "react-dom/client"; function App() { const location = useLocation(); // run a piece of code on location change useEffect(() => { console.log(location.pathname); // send it to analytic, or do some conditional logic here }, [location]); return <Routes> {/* routes here... */} </Routes> } createRoot(document.querySelector("#react-root")).render(<BrowserRouter><App /></BrowserRouter>);
Chaque fois que l'utilisateur se déplace vers un nouvel itinéraire pendant la navigation, le code à l'intérieur du hook useEffect
s'exécutera et fera son travail. C'est essentiellement un moyen de s'assurer qu'un code spécifique est exécuté chaque fois qu'il y a un changement dans l'objet de localisation.
Pour conclure, cet article vous a permis de mieux comprendre React Router. Bien que vous ne puissiez pas utiliser toutes les fonctionnalités décrites ici. C'est quand même fantastique que vous les connaissiez. Si jamais vous avez besoin d'intégrer des fonctionnalités similaires à l'avenir, vous savez exactement où chercher. Alors, assurez-vous de sauvegarder ou de mettre en signet ce message pour une référence facile. Et rappelez-vous, si vous avez des questions ou avez besoin d'aide supplémentaire, n'hésitez pas à me contacter sur Twitter. Je suis là pour vous aider !