Ich freue mich wirklich, Ihnen heute einige fortgeschrittene React Router-Techniken vorstellen zu können. React Router ist ein erstaunliches Tool, mit dem wir eine dynamische und reibungslose Navigation in unseren React- Anwendungen erstellen können.
Während es üblicherweise für grundlegende Routing-Anforderungen verwendet wird, gibt es einige weniger bekannte Techniken, die Ihre Routing-Fähigkeiten auf ein ganz neues Niveau heben können.
Heute teile ich einige meiner Favoriten, die ich im Laufe der Zeit entdeckt habe.
useNavigate
und useLocation
.
Wenn Sie diesen Artikel zu Ende gelesen haben, werden Sie diese fortgeschrittenen React Router-Techniken gut beherrschen und sich sicher fühlen, sie in Ihren eigenen Projekten anzuwenden.
Also lasst uns gleich loslegen und gemeinsam unsere Routing-Fähigkeiten verbessern!
Sind Sie bereit? Lass uns anfangen!
Bei größeren Projekten ist es wichtig, sich um Routen zu kümmern, die nicht gefunden werden können. Wir bezeichnen diese Routen oft als 404-Routen , da sie den HTTP-Statuscode 404 zurückgeben, wenn ein Dokument nicht auf dem Server gefunden wird.
Übrigens, wenn Sie ein Katzenliebhaber sind, könnte es Ihnen gefallen, http.cat auszuprobieren.
Lassen Sie uns nun mit der Erstellung einer speziellen Route beginnen, die immer dann ausgelöst wird, wenn keine der anderen Routen mit der aktuellen URL im Browser übereinstimmt.
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> }
Beim Zugriff auf die Primärseite /
werden Benutzer zur Zielseite weitergeleitet. Wenn sie zur Seite /products
navigieren, werden sie zur Seite „Produkte“ weitergeleitet. Werden jedoch weitere Links aufgerufen, die keiner bestimmten Route entsprechen, wird die 404-Seite angezeigt.
Der Grund für dieses Verhalten ist die Implementierung einer speziellen <Route>
für die 404-Seite, bei der die Pfadeigenschaft auf *
festgelegt ist. Diese Konfiguration stellt sicher, dass React Router diese Route ausschließlich verwendet, wenn keine anderen Routen übereinstimmen können. Die spezifische Platzierung der 404-Route spielt keine Rolle und kann als integraler Bestandteil an einer beliebigen Stelle im Abschnitt <Routes>...</Routes>
positioniert werden.
Eine weitere praktische Möglichkeit für Apps, Routen zu nutzen, besteht darin, die aktuell aktive Seite im Menü hervorzuheben.
Startseite – Dieser Link führt den Benutzer zur Hauptseite /
.
About – Dieser Link führt den Benutzer zur About-Seite /about
.
Mit React Router wird es möglich, den About
Link automatisch hervorzuheben, wenn sich der Benutzer auf der /about
Route befindet. Ebenso können Sie den Home-Link markieren, wenn sich der Benutzer auf der /
-Route befindet. Das Beste daran ist, dass Sie dies erreichen können, ohne dass komplexe Bedingungen erforderlich sind.
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> }
Der Code, den Sie oben sehen, benötigt etwas CSS, damit die active
Klasse funktioniert. Wir können es also verbessern, indem wir den Menülink der aktuell aktiven Seite fett und hervorstechen lassen.
.active { font-weight: bold; }
Das className
Attribut des NavLink
Elements bietet die Flexibilität, eine Funktion anstelle nur einer Zeichenfolge zu akzeptieren. Wenn Sie sich entscheiden, eine Funktion zu verwenden, wird ihr ein Objekt als Parameter zugewiesen, und für dieses Objekt ist die Eigenschaft isActive
bereits festgelegt. Um innerhalb der Funktion einfach auf diese Eigenschaft zugreifen zu können, verwenden wir die Destrukturierung, indem wir {isActive}
in den Parameter aufnehmen.
Als Nächstes überprüfen wir, ob isActive
einen wahrheitsgemäßen Wert enthält. Wenn das der Fall ist, geben wir den CSS- Klassennamen active
zurück.
Wenn der aktuelle Pfad in React Router mit dem to
Attribut der NavLink
Komponente übereinstimmt, wird die Funktion isActive
zu einem booleschen Wert ausgewertet.
Infolgedessen fügt React Router die active
Klasse nahtlos in das entsprechende <NavLink />
Element ein und gibt sie als aktuell aktive Route an.
Wenn Sie einen kürzeren Ansatz bevorzugen, können Sie den oben genannten Code mit dem ternären Operator umgestalten. Dieser Operator bietet eine Möglichkeit, eine if/else-Anweisung durch Verwendung des folgenden Formats zu ersetzen: condition ? truthy expression : falsy expression
.
Ich verwende den ternären Operator nicht wirklich oft, da er den Code oft weniger lesbar macht. In diesem Fall ist die Verwendung jedoch akzeptabel.
function getClassName({isActive}) { if (isActive) { return "active"; } else { return ""; } }
function getClassName({isActive}) { return isActive ? "active" : ""; }
Sie müssen lediglich sicherstellen, dass die Return-Anweisung außerhalb des ternären Operators platziert wird. Wenn die isActive
Bedingung wahr ist, wird der Ausdruck nach ?
wird "active"
ausgeführt. Andernfalls wird der Ausdruck nach :
""
.
Jetzt können wir die Notwendigkeit einer separaten Funktionsdefinition namens getClassName
beseitigen. Stattdessen können wir eine Pfeilfunktion wie diese verwenden: ({isActive}) => isActive ? "active" : ""
.
Wenn Ihnen diese Änderung zu schwer lesbar ist, können Sie wie bisher eine separate Funktion weiterverwenden.
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 Mann, ich kann deine Gedanken praktisch hören!
Sojin, du hast das DRY-Prinzip gebrochen, nicht wahr?
Dies ist nur ein Beispiel. Kein Grund, sich aufzuregen 😀
Sie haben vielleicht schon bemerkt, dass ich NavLink
anstelle unseres üblichen Freundes Link
verwende. Aber keine Sorge, lassen Sie mich erklären, warum. Sie sehen, die <Link />
Komponente erlaubt Ihnen nicht, eine Funktionsdefinition für die className
Requisite zu verwenden. Ja, es mag überraschend sein, aber so ist es eben, wenn Sie mit <Link />
arbeiten.
Ein häufiger Fehler, den ich gesehen habe, ist, dass junge React-Entwickler versuchen, Funktionsdefinitionen in der className
Requisite einer <Link />
Komponente zu verwenden, was einfach nicht funktioniert.
Wenn Sie Interesse haben, kann ich einen Artikel zu diesem Thema schreiben. Lass es mich einfach in den Kommentaren wissen!
Unter bestimmten Umständen müssen Sie möglicherweise Seiten innerhalb Ihrer React-Anwendung programmgesteuert verschieben. Um den Besucher beispielsweise auf eine bestimmte Seite umzuleiten, können Sie eine Anfrage stellen und auf die Antwort warten.
/dashboard
um.
Dies erfordert die Verwendung des useNavigate()
-Hooks, der eine Funktion zurückgibt, mit der Sie den Benutzer programmgesteuert auf eine neue Route umleiten können.
Schau mal:
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>; }
In diesem Beispiel prüfen wir, ob dem Schlüssel isLoggedIn
für „localStorage“ ein Wert zugewiesen ist. Ist dies nicht der Fall, leiten wir den Benutzer mithilfe der Funktion navigate("/login")
zur Seite /login
weiter.
Damit es funktioniert, denken Sie einfach daran, den useNavigate()
Hook innerhalb einer Komponente zu verwenden, die in der <BrowserRouter />
Komponente verschachtelt ist. Andernfalls funktioniert es nicht richtig.
Das folgende Beispiel funktioniert beispielsweise nicht:
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>; }
Wenn Sie versuchen, den useNavigate()
Hook innerhalb der App()
Komponente zu verwenden, könnte es zu einem kleinen Schluckauf kommen. Das liegt daran, dass es nicht funktioniert, wenn Sie die App()
Komponente nicht mit <BrowserRouter />
umschließen.
Aber keine Sorge!
Die gute Nachricht ist, dass alle untergeordneten Komponenten in App automatisch von <BrowserRouter />
umschlossen werden, sodass Sie useNavigate()
problemlos und ohne Probleme in diesen untergeordneten Komponenten verwenden können.
Wenn Sie jedoch useNavigate()
wirklich in der <App />
Komponente selbst verwenden müssen, gibt es eine einfache Lösung. Sie müssen lediglich eine übergeordnete Komponente erstellen, die <App />
umschließt, und sicherstellen, dass <BrowserRouter />
innerhalb dieser übergeordneten Komponente verschoben wird. Sobald Sie das getan haben, können Sie useNavigate()
in der <App />
Komponente nach Herzenslust verwenden 💗
Wenn Sie Ihre Website barrierefrei gestalten möchten, ist es wichtig, auf die Struktur Ihrer Links zu achten. Um dies sicherzustellen, wird empfohlen, <Link />
Elemente anstelle anderer Methoden zu verwenden.
Warum?
Nun, diese Elemente werden automatisch als <a>
-Tags gerendert, die für ihre Barrierefreiheitsfunktionen bekannt sind.
Hier ist ein freundlicher Tipp: Vermeiden Sie es, Ihre normalen <Link />
Elemente durch die von useNavigate()
bereitgestellte .push()
Methode zu ersetzen. Diese Methode sollte nur in Fällen verwendet werden, in denen die Verwendung eines <Link />
Elements nicht möglich ist.
Typischerweise ist dies der Fall, wenn Sie Benutzer programmgesteuert auf der Grundlage einer bestimmten Logik umleiten müssen, beispielsweise dem Ergebnis einer fetch()
Operation.
Was wäre, wenn Sie jedes Mal einen Code ausführen möchten, wenn React Router Sie zu einer neuen Adresse führt?
Dies können Sie ganz einfach mit Hilfe des useLocation
Hooks erreichen. Aber bevor wir uns mit den Details befassen, wollen wir einige Szenarien untersuchen, in denen dies nützlich sein kann. Einer der häufigsten Anwendungsfälle ist das Senden eines Seitenaufrufereignisses an Ihren Analysedienst wie Google Analytics.
Erwähnenswert ist jedoch, dass Google Analytics 4 dies jetzt automatisch erledigt, sodass Sie es nicht unbedingt selbst implementieren müssen.
Dennoch ist es immer noch wertvoll, etwas über den useLocation
Hook zu lernen, da Sie möglicherweise andere Verwendungszwecke dafür finden. Sie können es beispielsweise zur Integration mit anderen Bibliotheken und Analysediensten verwenden oder bestimmte Aktionen basierend auf den besuchten Routen ausführen.
Die Möglichkeiten sind endlos!
Der useLocation
Hook ist sehr praktisch, da er Ihnen Informationen über die aktuell verwendete Route liefert.
Hier ist eine benutzerfreundliche Anleitung zur Verwendung des useLocation-Hooks:
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>);
Jetzt können Sie über die Standortvariable auf die Routeninformationen zugreifen. Es ist ein Objekt, das den aktuellen pathname
enthält.
Um herauszufinden, welche Route der Benutzer gerade durchsucht, verwenden Sie einfach location.pathname
. Sie erhalten so etwas wie /
, /about
oder jede andere Route, die Sie eingerichtet haben.
Denken Sie daran, dass es genau wie beim useNavigate
Hook wichtig ist, dass Ihr Code in einer Komponente ausgeführt wird, die von <BrowserRouter />
umschlossen ist. Andernfalls wird der useLocation
Hook seine Wirkung nicht entfalten.
Wenn sich der Standort ändert, können Sie den useLocation
Hook verwenden, um auf den aktuellen URL-Pfad in React Router zuzugreifen. Indem Sie Ihren Code mit einem useEffect
Hook umschließen und die Abhängigkeit auf location
setzen, können Sie einen bestimmten Codeabschnitt immer dann ausführen, wenn eine Navigation zu einer neuen URL erfolgt.
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>);
Immer wenn der Benutzer während der Navigation zu einer neuen Route wechselt, wird der Code im useEffect
Hook ausgeführt und erledigt seine Aufgabe. Dies ist im Grunde eine Möglichkeit, sicherzustellen, dass bei jeder Änderung des Standortobjekts ein bestimmter Code ausgeführt wird.
Zum Abschluss hat Ihnen dieser Artikel ein tieferes Verständnis von React Router vermittelt. Möglicherweise nutzen Sie jedoch nicht alle hier besprochenen Funktionen. Dennoch ist es fantastisch, dass Sie sich dessen bewusst sind. Wenn Sie jemals feststellen, dass Sie in Zukunft ähnliche Funktionen integrieren müssen, wissen Sie genau, wo Sie suchen müssen. Speichern Sie diesen Beitrag also unbedingt ab oder markieren Sie ihn mit einem Lesezeichen, damit Sie ihn leichter nachschlagen können. Und denken Sie daran: Wenn Sie Fragen haben oder weitere Hilfe benötigen, können Sie mich gerne auf Twitter kontaktieren. Ich bin hier um zu helfen!