Clientseitiges Routing in Next.js
Veröffentlicht: 2022-03-10Hyperlinks sind seit seiner Einführung eines der Juwelen des Webs. Laut MDN machen Hyperlinks das Web zu einem Web. Während es für Zwecke wie das Verlinken zwischen Dokumenten verwendet wird, besteht seine Hauptverwendung darin, auf verschiedene Webseiten zu verweisen, die durch eine eindeutige Webadresse oder eine URL identifizierbar sind.
Routing ist ein ebenso wichtiger Aspekt jeder Webanwendung wie Hyperlinks zum Web. Es ist ein Mechanismus, durch den Anforderungen an den Code weitergeleitet werden, der sie verarbeitet. In Bezug auf das Routing werden Next.js-Seiten durch einen eindeutigen URL-Pfad referenziert und sind identifizierbar. Wenn das Web aus Navigationswebseiten besteht, die durch Hyperlinks miteinander verbunden sind, dann besteht jede Next.js-App aus routenfähigen Seiten (Routen-Handlern oder Routen), die durch einen Router miteinander verbunden sind.
Next.js verfügt über eine integrierte Unterstützung für das Routing, das unhandlich zu entpacken sein kann, insbesondere wenn Rendering und Datenabruf in Betracht gezogen werden. Als Voraussetzung für das Verständnis des clientseitigen Routings in Next.js ist es notwendig, einen Überblick über Konzepte wie Routing, Rendering und Datenabruf in Next.js zu haben.
Dieser Artikel ist für React-Entwickler hilfreich, die mit Next.js vertraut sind und erfahren möchten, wie es mit dem Routing umgeht. Sie müssen über praktische Kenntnisse von React und Next.js verfügen, um das Beste aus dem Artikel herauszuholen, in dem es ausschließlich um clientseitiges Routing und verwandte Konzepte in Next.js geht.
Routing und Rendering
Routing und Rendering ergänzen sich gegenseitig und werden im Verlauf dieses Artikels eine große Rolle spielen. Mir gefällt, wie Gaurav sie erklärt:
Routing ist der Prozess, durch den der Benutzer zu verschiedenen Seiten einer Website navigiert wird.
Beim Rendern werden diese Seiten auf der Benutzeroberfläche platziert. Jedes Mal, wenn Sie eine Route zu einer bestimmten Seite anfordern, rendern Sie auch diese Seite, aber nicht jedes Rendern ist das Ergebnis einer Route.
Nehmen Sie sich fünf Minuten Zeit, um darüber nachzudenken.
Was Sie über das Rendern in Next.js wissen müssen, ist, dass jede Seite im Voraus zusammen mit dem minimalen JavaScript-Code vorgerendert wird, der erforderlich ist, damit sie durch einen Prozess, der als Hydratation bekannt ist, vollständig interaktiv wird. Wie Next.js dies tut, hängt stark von der Form des Vorab-Renderings ab: statische Generierung oder serverseitiges Rendering , die beide stark an die verwendete Datenabruftechnik gekoppelt sind und davon getrennt werden, wann der HTML-Code für eine Seite generiert wird.
Abhängig von Ihren Datenabrufanforderungen verwenden Sie möglicherweise integrierte Datenabruffunktionen wie getStaticProps
, getStaticPaths
oder getServerSideProps
, clientseitige Datenabruftools wie SWR, React-Query oder herkömmliche Datenabrufansätze wie fetch-on- Rendern, Holen-dann-Rendern, Rendern-wie-du-holen (mit Suspense).
Pre-Rendering (vor dem Rendern – an die Benutzeroberfläche ) ist komplementär zu Routing und stark mit dem Abrufen von Daten gekoppelt – ein ganz eigenes Thema in Next.js. Obwohl diese Konzepte entweder komplementär oder eng miteinander verwandt sind, konzentriert sich dieser Artikel ausschließlich auf die bloße Navigation zwischen Seiten (Routing), gegebenenfalls mit Verweisen auf verwandte Konzepte.
Lassen Sie uns mit dem grundlegenden Kern beginnen: Next.js verfügt über einen dateisystembasierten Router, der auf dem Konzept von Seiten basiert.
Seiten
Seiten in Next.js sind React-Komponenten, die automatisch als Routen verfügbar sind. Sie werden als Standardexporte aus dem Seitenverzeichnis mit unterstützten Dateierweiterungen wie .js
, .jsx
, .ts
oder .tsx
.
Eine typische Next.js-App hat eine Ordnerstruktur mit Verzeichnissen der obersten Ebene wie pages , public und styles.
next-app ├── node_modules ├── pages │ ├── index.js // path: base-url (/) │ ├── books.jsx // path: /books │ └── book.ts // path: /book ├── public ├── styles ├── .gitignore ├── package.json └── README.md
Jede Seite ist eine React-Komponente:
// pages/books.js — `base-url/book` export default function Book() { return
Bücher
}
Hinweis : Denken Sie daran, dass Seiten auch als „Route Handler“ bezeichnet werden können.
Benutzerdefinierte Seiten
Dies sind spezielle Seiten , die sich im Seitenverzeichnis befinden, aber nicht am Routing teilnehmen. Ihnen ist ein Unterstrich vorangestellt, wie in _app.js
und _document.js
.
-
_app.js
Dies ist eine benutzerdefinierte Komponente, die sich im Seitenordner befindet. Next.js verwendet diese Komponente, um Seiten zu initialisieren. -
_document.js
Wie_app.js
ist_document.js
eine benutzerdefinierte Komponente, die Next.js verwendet, um die<html>
- und<body>
-Tags Ihrer Anwendung zu erweitern. Dies ist erforderlich, da Next.js-Seiten die Definition des Markups des umgebenden Dokuments überspringen.
next-app ├── node_modules ├── pages │ ├── _app.js // ️ Custom page (unavailable as a route) │ ├── _document.jsx // ️ Custom page (unavailable as a route) │ └── index.ts // path: base-url (/) ├── public ├── styles ├── .gitignore ├── package.json └── README.md
Verlinkung zwischen Seiten
Next.js stellt eine Link
-Komponente aus der next/link
-API bereit, die verwendet werden kann, um clientseitige Routenübergänge zwischen Seiten durchzuführen.
// Import the <Link/> component import Link from "next/link"; // This could be a page component export default function TopNav() { return ( <nav> <Link href="/">Home</Link> <Link href="/">Publications</Link> <Link href="/">About</Link> </nav> ) } // This could be a non-page component export default function Publications() { return ( <section> <TopNav/> {/* ... */} </section> ) }
Die Link
-Komponente kann innerhalb jeder Komponente verwendet werden, Seite oder nicht. Wenn sie in ihrer einfachsten Form wie im obigen Beispiel verwendet wird, wird die Link
-Komponente in einen Hyperlink mit einem href
-Attribut übersetzt. (Mehr zu Link
im nächsten/Link-Abschnitt unten.)
Routing
Das dateibasierte Routingsystem Next.js kann verwendet werden, um die gängigsten Routenmuster zu definieren. Um diese Muster zu berücksichtigen, wird jede Route basierend auf ihrer Definition getrennt.
Indexrouten
Standardmäßig ist in Ihrer Next.js-App die Anfangs-/Standardroute pages/index.js
, die automatisch als Ausgangspunkt Ihrer Anwendung als /
dient. Mit einer Basis-URL von localhost:3000
kann auf diese Indexroute auf Basis-URL-Ebene der Anwendung im Browser zugegriffen werden.
Indexrouten fungieren automatisch als Standardroute für jedes Verzeichnis und können Namensredundanzen eliminieren. Die folgende Verzeichnisstruktur macht zwei Routenpfade verfügbar: /
und /home
.
next-app └── pages ├── index.js // path: base-url (/) └── home.js // path: /home
Die Eliminierung ist bei verschachtelten Routen offensichtlicher.
Verschachtelte Routen
Eine Route wie pages/book
ist eine Ebene tief. Um tiefer zu gehen, müssen verschachtelte Routen erstellt werden, was eine verschachtelte Ordnerstruktur erfordert. Mit einer Basis-URL von https://www.smashingmagazine.com
können Sie auf die Route https://www.smashingmagazine.com/printed-books/printed-books
zugreifen, indem Sie eine Ordnerstruktur ähnlich der folgenden erstellen:
next-app └── pages ├── index.js // top index route └── printed-books // nested route └── printed-books.js // path: /printed-books/printed-books
Oder beseitigen Sie die Pfadredundanz mit Indexrouten und greifen Sie auf die Route für gedruckte Bücher unter https://www.smashingmagazine.com/printed-books
zu.
next-app └── pages ├── index.js // top index route └── printed-books // nested route └── index.js // path: /printed-books
Dynamische Routen spielen auch eine wichtige Rolle bei der Eliminierung von Redundanzen.
Dynamische Routen
Aus dem vorherigen Beispiel verwenden wir die Indexroute, um auf alle gedruckten Bücher zuzugreifen. Um auf einzelne Bücher zuzugreifen, müssen Sie entweder unterschiedliche Routen für jedes Buch erstellen, wie z.
// ️ Don't do this. next-app └── pages ├── index.js // top index route └── printed-books // nested route ├── index.js // path: /printed-books ├── typesript-in-50-lessons.js // path: /printed-books/typesript-in-50-lessons ├── checklist-cards.js // path: /printed-books/checklist-cards ├── ethical-design-handbook.js // path: /printed-books/ethical-design-handbook ├── inclusive-components.js // path: /printed-books/inclusive-components └── click.js // path: /printed-books/click
Das ist hochredundant, nicht skalierbar und kann mit dynamischen Routen behoben werden wie:
// Do this instead. next-app └── pages ├── index.js // top index route └── printed-books ├── index.js // path: /printed-books └── [book-id].js // path: /printed-books/:book-id
Die Klammersyntax – [book-id]
– ist das dynamische Segment und nicht nur auf Dateien beschränkt. Es kann auch mit Ordnern wie im folgenden Beispiel verwendet werden, wodurch der Autor unter der Route /printed-books/:book-id/author
verfügbar wird.
next-app └── pages ├── index.js // top index route └── printed-books ├── index.js // path: /printed-books └── [book-id] └── author.js // path: /printed-books/:book-id/author
Das/die dynamische(n) Segment(e) einer Route wird/werden als Abfrageparameter verfügbar gemacht, auf den in jeder der an der Route beteiligten Verbindungskomponenten mit dem query
des useRouter()
-Hooks zugegriffen werden kann – (Mehr dazu im nächsten/Router-API-Abschnitt ).
// printed-books/:book-id import { useRouter } from 'next/router'; export default function Book() { const { query } = useRouter(); return ( <div> <h1> book-id <em>{query['book-id']}</em> </h1> </div> ); }
// /printed-books/:book-id/author import { useRouter } from 'next/router'; export default function Author() { const { query } = useRouter(); return ( <div> <h1> Fetch author with book-id <em>{query['book-id']}</em> </h1> </div> ); }
Erweitern dynamischer Routensegmente mit Catch All Routes
Sie haben die Klammersyntax für dynamische Routensegmente wie im vorherigen Beispiel mit [book-id].js
. Das Schöne an dieser Syntax ist, dass sie mit Catch-All Routes noch weiter geht. Was das macht, kannst du dem Namen entnehmen: Es fängt alle Routen ab.
Als wir uns das dynamische Beispiel angesehen haben, haben wir gelernt, wie es dazu beiträgt, die Redundanz bei der Dateierstellung für eine einzelne Route zu beseitigen, um auf mehrere Bücher mit ihrer ID zuzugreifen. Aber es gibt noch etwas, was wir hätten tun können.
Insbesondere hatten wir den Pfad /printed-books/:book-id
mit einer Verzeichnisstruktur:
next-app └── pages ├── index.js └── printed-books ├── index.js └── [book-id].js
Wenn wir den Pfad aktualisieren, um mehr Segmente wie Kategorien zu haben, könnten wir am Ende so etwas wie: /printed-books/design/:book-id
, /printed-books/engineering/:book-id
, oder noch besser /printed-books/:category/:book-id
.
Fügen wir das Erscheinungsjahr hinzu: /printed-books/:category/:release-year/:book-id
. Können Sie ein Muster erkennen? Die Verzeichnisstruktur wird zu:
next-app └── pages ├── index.js └── printed-books └── [category] └── [release-year] └── [book-id].js
Wir haben die Verwendung benannter Dateien durch dynamische Routen ersetzt, sind aber irgendwie immer noch bei einer anderen Form der Redundanz gelandet. Nun, es gibt eine Lösung: Catch All Routes, die die Notwendigkeit für tief verschachtelte Routen eliminiert:
next-app └── pages ├── index.js └── printed-books └── [...slug].js
Es verwendet dieselbe Klammersyntax, außer dass ihm drei Punkte vorangestellt sind. Stellen Sie sich die Punkte wie die Spread-Syntax von JavaScript vor. Sie fragen sich vielleicht: Wenn ich die Catch-all-Routen verwende, wie greife ich auf die Kategorie ( [category]
) und das Erscheinungsjahr ( [release-year]
) zu? Zwei Wege:
- Im Fall des Beispiels der gedruckten Bücher ist das Endziel das Buch, und jeder Buchinfo werden ihre Metadaten angehängt, oder
- Die „Slug“-Segmente werden als Array von Abfrageparametern zurückgegeben.
import { useRouter } from 'next/router'; export default function Book() { const { query } = useRouter(); // There's a brief moment where `slug` is undefined // so we use the Optional Chaining (?.) and Nullish coalescing operator (??) // to check if slug is undefined, then fall back to an empty array const [category, releaseYear, bookId] = query?.slug ?? []; return ( <table> <tbody> <tr> <th>Book Id</th> <td>{bookId}</td> </tr> <tr> <th>Category</th> <td>{category}</td> </tr> <tr> <th>Release Year</th> <td>{releaseYear}</td> </tr> </tbody> </table> ); }
Hier ist ein weiteres Beispiel für die Route /printed-books/[…slug]
:
Weg | Abfrageparameter |
---|---|
/printed-books/click.js | { „Schnecke“: [„Klick“] } |
/printed-books/2020/click.js | { „Schnecke“: [„2020“, „Klick“] } |
/printed-books/design/2020/click.js | { „Slug“: [„Design“, „2020“, „Klick“] } |
Wie bei der Catch-All-Route gibt die Route /printed-books
einen 404-Fehler aus, es sei denn, Sie geben eine Fallback-Indexroute an.
next-app └── pages ├── index.js └── printed-books ├── index.js // path: /printed-books └── [...slug].js
Dies liegt daran, dass die Auffangroute „streng“ ist. Entweder stimmt es mit einem Slug überein oder es wird ein Fehler ausgegeben. Wenn Sie das Erstellen von Indexrouten neben Catch-All-Routen vermeiden möchten, können Sie stattdessen die optionalen Catch-All-Routen verwenden.
Erweiterung dynamischer Routensegmente mit optionalen Catch-All-Routen
Die Syntax ist dieselbe wie bei Catch-All-Routes, jedoch mit doppelten eckigen Klammern.
next-app └── pages ├── index.js └── printed-books └── [[...slug]].js
In diesem Fall ist die Catch-All-Route (Slug) optional und wird, falls nicht verfügbar, auf den Pfad /printed-books
zurückgegriffen, der mit dem [[…slug]].js
-Routenhandler ohne Abfrageparameter gerendert wird.
Verwenden Sie Catch-All neben Indexrouten oder optional Catch-All-Routen allein. Vermeiden Sie die Verwendung von Catch-all- und optionalen Catch-all-Routen daneben.
Vorrang der Routen
Die Fähigkeit, die gängigsten Routing-Muster definieren zu können, kann ein „schwarzer Schwan“ sein. Die Möglichkeit, dass Routen kollidieren, ist eine drohende Bedrohung, insbesondere wenn Sie anfangen, dynamische Routen auszuarbeiten.
Wenn es sinnvoll ist, informiert Sie Next.js über Routenkollisionen in Form von Fehlern. Wenn dies nicht der Fall ist, wird den Routen entsprechend ihrer Spezifität Vorrang eingeräumt.
Beispielsweise ist es ein Fehler, mehr als eine dynamische Route auf derselben Ebene zu haben.
// This is an error // Failed to reload dynamic routes: Error: You cannot use different slug names for the // same dynamic path ('book-id' !== 'id'). next-app └── pages ├── index.js └── printed-books ├── [book-id].js └── [id].js
Wenn Sie sich die unten definierten Routen genau ansehen, werden Sie das Potenzial für Konflikte bemerken.
// Directory structure flattened for simplicity next-app └── pages ├── index.js // index route (also a predefined route) └── printed-books ├── index.js ├── tags.js // predefined route ├── [book-id].js // handles dynamic route └── [...slug].js // handles catch all route
Versuchen Sie beispielsweise, dies zu beantworten: Welche Route verarbeitet den Pfad /printed-books/inclusive-components
?
-
/printed-books/[book-id].js
, oder -
/printed-books/[…slug].js
.
Die Antwort liegt in der „Spezifität“ der Routen-Handler. Vordefinierte Routen kommen zuerst, gefolgt von dynamischen Routen und dann Catch-All-Routen. Sie können sich das Routenanforderungs-/Handhabungsmodell als Pseudocode mit den folgenden Schritten vorstellen:
- Gibt es einen vordefinierten Routenhandler , der die Route verarbeiten kann?
-
true
– behandelt die Routenanfrage. -
false
— gehe zu 2.
-
- Gibt es einen dynamischen Routenhandler , der die Route verarbeiten kann?
-
true
– behandelt die Routenanfrage. -
false
– gehe zu 3.
-
- Gibt es einen Catch-All-Routenhandler , der die Route handhaben kann?
-
true
– behandelt die Routenanfrage. -
false
– wirft eine 404-Seite, die nicht gefunden wurde.
-
Daher gewinnt /printed-books/[book-id].js
.
Hier sind weitere Beispiele:
Route | Routenhandler | Art der Strecke |
---|---|---|
/printed-books | /printed-books | Indexroute |
/printed-books/tags | /printed-books/tags.js | Vordefinierte Route |
/printed-books/inclusive-components | /printed-books/[book-id].js | Dynamische Strecke |
/printed-books/design/inclusive-components | /printed-books/[...slug].js | Catch-all-Route |
Die next/link
-API
Die next/link
-API macht die Link
-Komponente als deklarative Methode verfügbar, um clientseitige Routenübergänge durchzuführen.
import Link from 'next/link' function TopNav() { return ( <nav> <Link href="/">Smashing Magazine</Link> <Link href="/articles">Articles</Link> <Link href="/guides">Guides</Link> <Link href="/printed-books">Books</Link> </nav> ) }
Die Link
Komponente wird in einen regulären HTML-Hyperlink aufgelöst. Das heißt, <Link href="/">Smashing Magazine</Link>
wird in <a href="/">Smashing Magazine</a>
.
Das href
Prop ist das einzige erforderliche Prop für die Link
Komponente. In der Dokumentation finden Sie eine vollständige Liste der Requisiten, die für die Link
Komponente verfügbar sind.
Es gibt noch andere Mechanismen der Link
Komponente, die Sie beachten sollten.
Routen mit dynamischen Segmenten
Vor Link
9.5.3 bedeutete das Verknüpfen mit dynamischen Routen, dass Sie sowohl href
als auch as
prop für Link
bereitstellen mussten, wie in:
import Link from 'next/link'; const printedBooks = [ { name: 'Ethical Design', id: 'ethical-design' }, { name: 'Design Systems', id: 'design-systems' }, ]; export default function PrintedBooks() { return printedBooks.map((printedBook) => ( <Link href="/printed-books/[printed-book-id]" as={`/printed-books/${printedBook.id}`} > {printedBook.name} </Link> )); }
Obwohl dies Next.js ermöglichte, die href für die dynamischen Parameter zu interpolieren, war dies mühsam, fehleranfällig und etwas zwingend erforderlich und wurde nun mit der Veröffentlichung von Next.js 10 für die meisten Anwendungsfälle behoben.
Dieser Fix ist auch abwärtskompatibel. Wenn Sie sowohl as
als auch href
verwendet haben, geht nichts kaputt. Um die neue Syntax zu übernehmen, verwerfen Sie die href
und ihren Wert und benennen Sie die Eigenschaft as
in href
um, wie im folgenden Beispiel:
import Link from 'next/link'; const printedBooks = [ { name: 'Ethical Design', id: 'ethical-design' }, { name: 'Design Systems', id: 'design-systems' }, ]; export default function PrintedBooks() { return printedBooks.map((printedBook) => ( <Link href={`/printed-books/${printedBook.id}`}>{printedBook.name}</Link> )); }
Siehe Automatisches Auflösen von href.
Anwendungsfälle für die passHref
-Prop
Schauen Sie sich den folgenden Ausschnitt genau an:
import Link from 'next/link'; const printedBooks = [ { name: 'Ethical Design', id: 'ethical-design' }, { name: 'Design Systems', id: 'design-systems' }, ]; // Say this has some sort of base styling attached function CustomLink({ href, name }) { return <a href={href}>{name}</a>; } export default function PrintedBooks() { return printedBooks.map((printedBook) => ( <Link href={`/printed-books/${printedBook.id}`} passHref> <CustomLink name={printedBook.name} /> </Link> )); }
Die passHref
Props zwingen die Link
-Komponente, den href
-Requisit an die CustomLink
Komponente weiterzugeben. Dies ist obligatorisch, wenn die Link
-Komponente eine Komponente umschließt, die ein Hyperlink- <a>
-Tag zurückgibt. Ihr Anwendungsfall könnte darin bestehen, dass Sie eine Bibliothek wie styled-components verwenden oder mehrere untergeordnete Elemente an die Link
-Komponente übergeben müssen, da sie nur ein einziges untergeordnetes Element erwartet.
Weitere Informationen finden Sie in den Dokumenten.
URL-Objekte
Das href
Prop der Link
-Komponente kann auch ein URL-Objekt mit Eigenschaften wie query
sein, das automatisch in einen URL-String formatiert wird.
Mit dem Objekt printedBooks
wird das folgende Beispiel verknüpft mit:
-
/printed-books/ethical-design?name=Ethical+Design
and -
/printed-books/design-systems?name=Design+Systems
.
import Link from 'next/link'; const printedBooks = [ { name: 'Ethical Design', id: 'ethical-design' }, { name: 'Design Systems', id: 'design-systems' }, ]; export default function PrintedBooks() { return printedBooks.map((printedBook) => ( <Link href={{ pathname: `/printed-books/${printedBook.id}`, query: { name: `${printedBook.name}` }, }} > {printedBook.name} </Link> )); }
Wenn Sie ein dynamisches Segment in den pathname
, müssen Sie es auch als Eigenschaft in das Abfrageobjekt aufnehmen, um sicherzustellen, dass die Abfrage in den pathname
interpoliert wird:
import Link from 'next/link'; const printedBooks = [ { name: 'Ethical Design', id: 'ethical-design' }, { name: 'Design Systems', id: 'design-systems' }, ]; // In this case the dynamic segment `[book-id]` in pathname // maps directly to the query param `book-id` export default function PrintedBooks() { return printedBooks.map((printedBook) => ( <Link href={{ pathname: `/printed-books/[book-id]`, query: { 'book-id': `${printedBook.id}` }, }} > {printedBook.name} </Link> )); }
Das obige Beispiel hat Pfade:
-
/printed-books/ethical-design
und -
/printed-books/design-systems
.
Wenn Sie das href
-Attribut in VSCode untersuchen, finden Sie den Typ LinkProps
mit der Eigenschaft href
einen Url
-Typ, der entweder ein string
oder ein UrlObject
ist, wie bereits erwähnt.
Die Untersuchung des UrlObject
führt weiter zu der Schnittstelle mit den Eigenschaften:
Weitere Informationen zu diesen Eigenschaften finden Sie in der Dokumentation zum URL-Modul von Node.js.
Ein Anwendungsfall des Hashs besteht darin, auf bestimmte Abschnitte auf einer Seite zu verlinken.
import Link from 'next/link'; const printedBooks = [{ name: 'Ethical Design', id: 'ethical-design' }]; export default function PrintedBooks() { return printedBooks.map((printedBook) => ( <Link href={{ pathname: `/printed-books/${printedBook.id}`, hash: 'faq', }} > {printedBook.name} </Link> )); }
Der Hyperlink wird zu /printed-books/ethical-design#faq
.
Erfahren Sie mehr in den Dokumenten.
Die next/router
API
Wenn next/link
deklarativ ist, dann ist next/router
zwingend. Es macht einen useRouter
Hook verfügbar, der den Zugriff auf das router
-Objekt innerhalb jeder Funktionskomponente ermöglicht. Sie können diesen Hook verwenden, um das Routing manuell durchzuführen, insbesondere in bestimmten Szenarien, in denen der next/link
nicht ausreicht oder in denen Sie sich in das Routing „einhängen“ müssen.
import { useRouter } from 'next/router'; export default function Home() { const router = useRouter(); function handleClick(e) { e.preventDefault(); router.push(href); } return ( <button type="button" onClick={handleClick}>Click me</button> ) }
useRouter
ist ein React-Hook und kann nicht mit Klassen verwendet werden. Benötigen Sie das router
-Objekt in Klassenkomponenten? Mit withRouter
verwenden.
import { withRouter } from 'next/router'; function Home({router}) { function handleClick(e) { e.preventDefault(); router.push(href); } return ( <button type="button" onClick={handleClick}>Click me</button> ) } export default withRouter(Home);
Das router
-Objekt
Sowohl der Hook useRouter
als auch die Komponente höherer Ordnung withRouter
geben ein Router-Objekt mit Eigenschaften wie pathname
, query
, asPath
und basePath
, das Ihnen Informationen über den URL-Status der aktuellen Seite, locale
, locales
und defaultLocale
gibt, das Informationen über die aktives, unterstütztes oder aktuelles Standardgebietsschema.
Das Router-Objekt verfügt auch über Methoden wie push
zum Navigieren zu einer neuen URL durch Hinzufügen eines neuen URL-Eintrags zum Verlaufsstapel, replace
, ähnlich wie Push, ersetzt jedoch die aktuelle URL, anstatt einen neuen URL-Eintrag zum Verlaufsstapel hinzuzufügen.
Erfahren Sie mehr über das Router-Objekt.
Benutzerdefinierte Routenkonfiguration mit next.config.js
Dies ist ein reguläres Node.js-Modul, das verwendet werden kann, um bestimmte Verhaltensweisen von Next.js zu konfigurieren.
module.exports = { // configuration options }
Denken Sie daran, Ihren Server jedes Mal neu zu starten, wenn Sie
next.config.js
aktualisieren. Mehr erfahren.
Basispfad
Es wurde erwähnt, dass die Anfangs-/Standardroute in Next.js pages/index.js
mit dem Pfad /
ist. Dies ist konfigurierbar und Sie können Ihre Standardroute zu einem Unterpfad der Domäne machen.
module.exports = { // old default path: / // new default path: /dashboard basePath: '/dashboard', };
Diese Änderungen werden automatisch in Ihrer Anwendung wirksam, wobei alle /
-Pfade an /dashboard
weitergeleitet werden.
Diese Funktion kann nur mit Next.js 9.5 und höher verwendet werden. Mehr erfahren.
Schrägstrich
Standardmäßig ist am Ende jeder URL kein nachgestellter Schrägstrich verfügbar. Sie können dies jedoch ändern mit:
module.exports = { trailingSlash: true };
# trailingSlash: false /printed-books/ethical-design#faq # trailingSlash: true /printed-books/ethical-design/#faq
Sowohl der Basispfad als auch die nachgestellten Schrägstriche können nur mit Next.js 9.5 und höher verwendet werden.
Fazit
Routing ist einer der wichtigsten Teile Ihrer Next.js-Anwendung und spiegelt sich im dateisystembasierten Router wider, der auf dem Konzept von Seiten basiert. Seiten können verwendet werden, um die gängigsten Routenmuster zu definieren. Die Konzepte von Routing und Rendering sind eng miteinander verbunden. Nehmen Sie die Lektionen dieses Artikels mit, wenn Sie Ihre eigene Next.js-App erstellen oder an einer Next.js-Codebasis arbeiten. Und sehen Sie sich die Ressourcen unten an, um mehr zu erfahren.
Ähnliche Resourcen
- Offizielle Next.js-Dokumentation für Pages
- Offizielle Next.js-Dokumentation zum Abrufen von Daten
- Offizielle Next.js-Dokumentation für next.config.js
- Next.js 10: Automatische Auflösung von
href
- Offizielle Next.js-Dokumentation für next/link
- Next.js offizielle Dokumentation für next/router