Linking und Navigation
Der Next.js-Router ermöglicht clientseitige Routenübergänge zwischen Seiten, ähnlich wie bei einer Single-Page-Anwendung.
Eine React-Komponente namens Link
wird bereitgestellt, um diesen clientseitigen Routenwechsel durchzuführen.
import Link from 'next/link'
function Home() {
return (
<ul>
<li>
<Link href="/">Home</Link>
</li>
<li>
<Link href="/about">Über uns</Link>
</li>
<li>
<Link href="/blog/hello-world">Blog-Beitrag</Link>
</li>
</ul>
)
}
export default Home
Das obige Beispiel verwendet mehrere Links. Jeder davon ordnet einen Pfad (href
) einer bekannten Seite zu:
/
→pages/index.js
/about
→pages/about.js
/blog/hello-world
→pages/blog/[slug].js
Jeder <Link />
im sichtbaren Bereich (initial oder durch Scrollen) wird standardmäßig vorab geladen (inklusive der entsprechenden Daten) für Seiten, die Static Generation verwenden. Die entsprechenden Daten für server-seitig gerenderte Routen werden erst dann abgerufen, wenn auf den <Link />
geklickt wird.
Verlinkung zu dynamischen Pfaden
Sie können auch Interpolation verwenden, um den Pfad zu erstellen, was besonders nützlich für dynamische Routensegmente ist. Zum Beispiel, um eine Liste von Beiträgen anzuzeigen, die der Komponente als Prop übergeben wurden:
import Link from 'next/link'
function Posts({ posts }) {
return (
<ul>
{posts.map((post) => (
<li key={post.id}>
<Link href={`/blog/${encodeURIComponent(post.slug)}`}>
{post.title}
</Link>
</li>
))}
</ul>
)
}
export default Posts
encodeURIComponent
wird im Beispiel verwendet, um den Pfad utf-8-kompatibel zu halten.
Alternativ mit einem URL-Objekt:
import Link from 'next/link'
function Posts({ posts }) {
return (
<ul>
{posts.map((post) => (
<li key={post.id}>
<Link
href={{
pathname: '/blog/[slug]',
query: { slug: post.slug },
}}
>
{post.title}
</Link>
</li>
))}
</ul>
)
}
export default Posts
Hier verwenden wir statt Interpolation ein URL-Objekt in href
, wobei:
pathname
der Name der Seite impages
-Verzeichnis ist. In diesem Fall/blog/[slug]
.query
ein Objekt mit dem dynamischen Segment ist. Hierslug
.
Router einbinden
Beispiele
Um auf das router
-Objekt in einer React-Komponente zuzugreifen, können Sie useRouter
oder withRouter
verwenden.
Generell empfehlen wir die Verwendung von useRouter
.
Imperative Navigation
next/link
sollte die meisten Ihrer Routing-Anforderungen abdecken, aber Sie können auch clientseitige Navigationen ohne diese Komponente durchführen. Siehe die Dokumentation für next/router
.
Das folgende Beispiel zeigt grundlegende Seitennavigation mit useRouter
:
import { useRouter } from 'next/router'
export default function ReadMore() {
const router = useRouter()
return (
<button onClick={() => router.push('/about')}>
Hier klicken für mehr Informationen
</button>
)
}
Shallow Routing
Beispiele
Shallow Routing ermöglicht es, die URL zu ändern, ohne die Datenabrufmethoden erneut auszuführen. Dazu gehören getServerSideProps
, getStaticProps
und getInitialProps
.
Sie erhalten den aktualisierten pathname
und das query
-Objekt über das router
-Objekt (bereitgestellt durch useRouter
oder withRouter
), ohne den Zustand zu verlieren.
Um Shallow Routing zu aktivieren, setzen Sie die shallow
-Option auf true
. Betrachten Sie folgendes Beispiel:
import { useEffect } from 'react'
import { useRouter } from 'next/router'
// Aktuelle URL ist '/'
function Page() {
const router = useRouter()
useEffect(() => {
// Navigationen immer nach dem ersten Rendern durchführen
router.push('/?counter=10', undefined, { shallow: true })
}, [])
useEffect(() => {
// Der Zähler hat sich geändert!
}, [router.query.counter])
}
export default Page
Die URL wird auf /?counter=10
aktualisiert und die Seite wird nicht ersetzt, nur der Zustand der Route ändert sich.
Sie können URL-Änderungen auch über componentDidUpdate
überwachen, wie unten gezeigt:
componentDidUpdate(prevProps) {
const { pathname, query } = this.props.router
// Überprüfen, ob sich die Props geändert haben, um eine Endlosschleife zu vermeiden
if (query.counter !== prevProps.router.query.counter) {
// Daten basierend auf der neuen Abfrage abrufen
}
}
Einschränkungen
Shallow Routing funktioniert nur für URL-Änderungen auf der aktuellen Seite. Angenommen, wir haben eine weitere Seite namens pages/about.js
und Sie führen dies aus:
router.push('/?counter=10', '/about?counter=10', { shallow: true })
Da dies eine neue Seite ist, wird die aktuelle Seite entladen, die neue geladen und auf den Datenabruf gewartet, obwohl wir Shallow Routing angefordert haben.
Bei Verwendung mit Middleware stellt Shallow Routing nicht sicher, dass die neue Seite mit der aktuellen übereinstimmt, wie es zuvor ohne Middleware der Fall war. Dies liegt daran, dass Middleware dynamisch umschreiben kann und clientseitig ohne Datenabruf nicht überprüft werden kann, der bei Shallow Routing übersprungen wird. Daher muss eine Shallow-Route-Änderung immer als flach behandelt werden.