TanStack Router unterstützt eine Reihe von leistungsstarken Routing-Konzepten, mit denen Sie komplexe und dynamische Routing-Systeme einfach erstellen können.
Jedes dieser Konzepte ist nützlich und leistungsstark, und wir werden uns in den folgenden Abschnitten mit jedem einzelnen befassen.
Alle anderen Routen, außer der Root-Route, werden mit der createFileRoute Funktion konfiguriert, die Typsicherheit bei der Verwendung von dateibasiertem Routing bietet.
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/')({
component: PostsComponent,
})
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/')({
component: PostsComponent,
})
Die Funktion createFileRoute nimmt ein einziges Argument entgegen, den Pfad der Datei-Route als String.
❓❓❓ „Moment mal, Sie lassen mich den Pfad der Routendatei an createFileRoute übergeben?“
Ja! Aber keine Sorge, dieser Pfad wird automatisch vom Router für Sie über das TanStack Router Bundler Plugin oder die Router CLI geschrieben und verwaltet. Wenn Sie also neue Routen erstellen, Routen verschieben oder umbenennen, wird der Pfad automatisch für Sie aktualisiert.
Der Grund für diesen Pfadnamen hat alles mit der magischen Typsicherheit von TanStack Router zu tun. Ohne diesen Pfadnamen hätte TypeScript keine Ahnung, in welcher Datei wir uns befinden! (Wir wünschten, TypeScript hätte dafür eine eingebaute Funktion, aber das ist noch nicht der Fall 🤷♂️)
Die Root-Route ist die oberste Route im gesamten Baum und kapselt alle anderen Routen als Kinder.
Auch wenn sie keinen Pfad hat, hat die Root-Route Zugriff auf alle Funktionen wie andere Routen, einschließlich
Um eine Root-Route zu erstellen, rufen Sie die Funktion createRootRoute() auf und exportieren Sie sie als Route Variable in Ihrer Routendatei.
// Standard root route
import { createRootRoute } from '@tanstack/react-router'
export const Route = createRootRoute()
// Root route with Context
import { createRootRouteWithContext } from '@tanstack/react-router'
import type { QueryClient } from '@tanstack/react-query'
export interface MyRouterContext {
queryClient: QueryClient
}
export const Route = createRootRouteWithContext<MyRouterContext>()
// Standard root route
import { createRootRoute } from '@tanstack/react-router'
export const Route = createRootRoute()
// Root route with Context
import { createRootRouteWithContext } from '@tanstack/react-router'
import type { QueryClient } from '@tanstack/react-query'
export interface MyRouterContext {
queryClient: QueryClient
}
export const Route = createRootRouteWithContext<MyRouterContext>()
Um mehr über Kontext in TanStack Router zu erfahren, lesen Sie den Leitfaden Router Context.
Basic Routes entsprechen einem bestimmten Pfad, zum Beispiel sind /about, /settings, /settings/notifications allesamt Basic Routes, da sie dem Pfad exakt entsprechen.
Werfen wir einen Blick auf eine /about Route
// about.tsx
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/about')({
component: AboutComponent,
})
function AboutComponent() {
return <div>About</div>
}
// about.tsx
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/about')({
component: AboutComponent,
})
function AboutComponent() {
return <div>About</div>
}
Basic Routes sind einfach und unkompliziert. Sie entsprechen exakt dem Pfad und rendern die bereitgestellte Komponente.
Index-Routen zielen speziell auf ihre Elternroute ab, wenn diese exakt abgeglichen wird und keine Kindroute abgeglichen wird.
Werfen wir einen Blick auf eine Index-Route für eine /posts URL
// posts.index.tsx
import { createFileRoute } from '@tanstack/react-router'
// Note the trailing slash, which is used to target index routes
export const Route = createFileRoute('/posts/')({
component: PostsIndexComponent,
})
function PostsIndexComponent() {
return <div>Please select a post!</div>
}
// posts.index.tsx
import { createFileRoute } from '@tanstack/react-router'
// Note the trailing slash, which is used to target index routes
export const Route = createFileRoute('/posts/')({
component: PostsIndexComponent,
})
function PostsIndexComponent() {
return <div>Please select a post!</div>
}
Diese Route wird abgeglichen, wenn die URL genau /posts ist.
Routenpfadsegmente, die mit einem $ gefolgt von einem Label beginnen, sind dynamisch und erfassen diesen Teil der URL in das params Objekt zur Verwendung in Ihrer Anwendung. Zum Beispiel würde ein Pfadname von /posts/123 der Route /posts/$postId entsprechen, und das params Objekt wäre { postId: '123' }.
Diese Parameter sind dann in Ihrer Routenkonfiguration und Ihren Komponenten nutzbar! Sehen wir uns eine posts.$postId.tsx Route an.
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/posts/$postId')({
// In a loader
loader: ({ params }) => fetchPost(params.postId),
// Or in a component
component: PostComponent,
})
function PostComponent() {
// In a component!
const { postId } = Route.useParams()
return <div>Post ID: {postId}</div>
}
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/posts/$postId')({
// In a loader
loader: ({ params }) => fetchPost(params.postId),
// Or in a component
component: PostComponent,
})
function PostComponent() {
// In a component!
const { postId } = Route.useParams()
return <div>Post ID: {postId}</div>
}
🧠 Dynamische Segmente funktionieren in jedem Pfadsegment. Sie könnten zum Beispiel eine Route mit dem Pfad /posts/$postId/$revisionId haben, und jedes $ Segment würde im params Objekt erfasst.
Eine Route mit einem Pfad von nur $ wird als "Splat"-Route bezeichnet, da sie immer jeden verbleibenden Teil des URL-Pfadnamens vom $ bis zum Ende erfasst. Der erfasste Pfadname ist dann im params Objekt unter der speziellen Eigenschaft _splat verfügbar.
Zum Beispiel ist eine Route, die auf den Pfad files/$ abzielt, eine Splat-Route. Wenn der URL-Pfadname /files/documents/hello-world ist, enthält das params Objekt documents/hello-world unter der speziellen Eigenschaft _splat.
{
'_splat': 'documents/hello-world'
}
{
'_splat': 'documents/hello-world'
}
⚠️ In v1 des Routers werden Splat-Routen aus Kompatibilitätsgründen auch mit einem * anstelle eines _splat Schlüssels bezeichnet. Dies wird in v2 entfernt.
🧠 Warum $ verwenden? Dank Tools wie Remix wissen wir, dass *s, obwohl sie das gebräuchlichste Zeichen für Wildcards sind, nicht gut mit Dateinamen oder CLI-Tools harmonieren. Deshalb haben wir uns, genau wie sie, entschieden, $ stattdessen zu verwenden.
Optionale Pfadparameter ermöglichen es Ihnen, Routensegmente zu definieren, die in der URL vorhanden sein können oder nicht. Sie verwenden die Syntax {-$paramName} und bieten flexible Routing-Muster, bei denen bestimmte Parameter optional sind.
// posts.{-$category}.tsx - Optional category parameter
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/posts/{-$category}')({
component: PostsComponent,
})
function PostsComponent() {
const { category } = Route.useParams()
return <div>{category ? `Posts in ${category}` : 'All Posts'}</div>
}
// posts.{-$category}.tsx - Optional category parameter
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/posts/{-$category}')({
component: PostsComponent,
})
function PostsComponent() {
const { category } = Route.useParams()
return <div>{category ? `Posts in ${category}` : 'All Posts'}</div>
}
Diese Route stimmt sowohl mit /posts (Kategorie ist undefined) als auch mit /posts/tech (Kategorie ist "tech") überein.
Sie können auch mehrere optionale Parameter in einer einzigen Route definieren.
// posts.{-$category}.{-$slug}.tsx
export const Route = createFileRoute('/posts/{-$category}/{-$slug}')({
component: PostsComponent,
})
// posts.{-$category}.{-$slug}.tsx
export const Route = createFileRoute('/posts/{-$category}/{-$slug}')({
component: PostsComponent,
})
Diese Route entspricht /posts, /posts/tech und /posts/tech/hello-world.
🧠 Routen mit optionalen Parametern haben eine niedrigere Priorität als exakte Übereinstimmungen, wodurch sichergestellt wird, dass spezifischere Routen wie /posts/featured vor /posts/{-$category} abgeglichen werden.
Layout-Routen werden verwendet, um Kindrouten mit zusätzlichen Komponenten und Logik zu umschließen. Sie sind nützlich für
Werfen wir einen Blick auf eine Beispiel-Layout-Route namens app.tsx
routes/
├── app.tsx
├── app.dashboard.tsx
├── app.settings.tsx
routes/
├── app.tsx
├── app.dashboard.tsx
├── app.settings.tsx
Im obigen Baum ist app.tsx eine Layout-Route, die zwei Kindrouten umschließt: app.dashboard.tsx und app.settings.tsx.
Diese Baumstruktur wird verwendet, um die Kindrouten mit einer Layout-Komponente zu umschließen.
import { Outlet, createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/app')({
component: AppLayoutComponent,
})
function AppLayoutComponent() {
return (
<div>
<h1>App Layout</h1>
<Outlet />
</div>
)
}
import { Outlet, createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/app')({
component: AppLayoutComponent,
})
function AppLayoutComponent() {
return (
<div>
<h1>App Layout</h1>
<Outlet />
</div>
)
}
Die folgende Tabelle zeigt, welche Komponente(n) basierend auf der URL gerendert werden.
| URL-Pfad | Komponente |
|---|---|
| /app | <AppLayout> |
| /app/dashboard | <AppLayout><Dashboard> |
| /app/settings | <AppLayout><Settings> |
Da TanStack Router sowohl flache als auch Verzeichnis-basierte Routen unterstützt, können Sie die Routen Ihrer Anwendung auch mit Layout-Routen innerhalb von Verzeichnissen ausdrücken.
routes/
├── app/
│ ├── route.tsx
│ ├── dashboard.tsx
│ ├── settings.tsx
routes/
├── app/
│ ├── route.tsx
│ ├── dashboard.tsx
│ ├── settings.tsx
In diesem verschachtelten Baum ist die Datei app/route.tsx eine Konfiguration für die Layout-Route, die zwei Kindrouten umschließt: app/dashboard.tsx und app/settings.tsx.
Layout-Routen ermöglichen es Ihnen auch, Komponenten- und Loader-Logik für dynamische Routensegmente zu erzwingen.
routes/
├── app/users/
│ ├── $userId/
| | ├── route.tsx
| | ├── index.tsx
| | ├── edit.tsx
routes/
├── app/users/
│ ├── $userId/
| | ├── route.tsx
| | ├── index.tsx
| | ├── edit.tsx
Ähnlich wie Layout-Routen werden pfadlose Layout-Routen verwendet, um Kindrouten mit zusätzlichen Komponenten und Logik zu umschließen. Pfadlose Layout-Routen erfordern jedoch keinen übereinstimmenden Pfad in der URL und werden verwendet, um Kindrouten mit zusätzlichen Komponenten und Logik zu umschließen, ohne einen übereinstimmenden Pfad in der URL zu benötigen.
Pfadlose Layout-Routen werden mit einem Unterstrich (_) präfixiert, um anzuzeigen, dass sie "pfadlos" sind.
🧠 Der Teil des Pfads nach dem _ Präfix wird als ID der Route verwendet und ist erforderlich, da jede Route eindeutig identifizierbar sein muss, insbesondere bei der Verwendung von TypeScript, um Fehlertypen zu vermeiden und Autovervollständigung effektiv durchzuführen.
Werfen wir einen Blick auf ein Beispiel einer pfadlosen Layout-Route namens _pathlessLayout.tsx
routes/
├── _pathlessLayout.tsx
├── _pathlessLayout.a.tsx
├── _pathlessLayout.b.tsx
routes/
├── _pathlessLayout.tsx
├── _pathlessLayout.a.tsx
├── _pathlessLayout.b.tsx
Im obigen Baum ist _pathlessLayout.tsx eine pfadlose Layout-Route, die zwei Kindrouten umschließt: _pathlessLayout.a.tsx und _pathlessLayout.b.tsx.
Die Route _pathlessLayout.tsx wird verwendet, um die Kindrouten mit einer pfadlosen Layout-Komponente zu umschließen.
import { Outlet, createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/_pathlessLayout')({
component: PathlessLayoutComponent,
})
function PathlessLayoutComponent() {
return (
<div>
<h1>Pathless layout</h1>
<Outlet />
</div>
)
}
import { Outlet, createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/_pathlessLayout')({
component: PathlessLayoutComponent,
})
function PathlessLayoutComponent() {
return (
<div>
<h1>Pathless layout</h1>
<Outlet />
</div>
)
}
Die folgende Tabelle zeigt, welche Komponente basierend auf der URL gerendert wird.
| URL-Pfad | Komponente |
|---|---|
| / | <Index> |
| /a | <PathlessLayout><A> |
| /b | <PathlessLayout><B> |
Da TanStack Router sowohl flache als auch Verzeichnis-basierte Routen unterstützt, können Sie die Routen Ihrer Anwendung auch mit pfadlosen Layout-Routen innerhalb von Verzeichnissen ausdrücken.
routes/
├── _pathlessLayout/
│ ├── route.tsx
│ ├── a.tsx
│ ├── b.tsx
routes/
├── _pathlessLayout/
│ ├── route.tsx
│ ├── a.tsx
│ ├── b.tsx
Im Gegensatz zu Layout-Routen stimmen pfadlose Layout-Routen jedoch nicht mit URL-Pfadsegmenten überein. Das bedeutet, dass diese Routen keine dynamischen Routensegmente als Teil ihres Pfades unterstützen und daher nicht in der URL abgeglichen werden können.
Das bedeutet, dass Sie das nicht tun können
routes/
├── _$postId/ ❌
│ ├── ...
routes/
├── _$postId/ ❌
│ ├── ...
Stattdessen müssten Sie das tun
routes/
├── $postId/
├── _postPathlessLayout/ ✅
│ ├── ...
routes/
├── $postId/
├── _postPathlessLayout/ ✅
│ ├── ...
Nicht-verschachtelte Routen können durch Anhängen eines _ an ein Eltern-Dateisegment erstellt werden und werden verwendet, um eine Route von ihren Eltern zu ent-verschachteln und ihren eigenen Komponentenbaum zu rendern.
Betrachten Sie den folgenden flachen Routenbaum.
routes/
├── posts.tsx
├── posts.$postId.tsx
├── posts_.$postId.edit.tsx
routes/
├── posts.tsx
├── posts.$postId.tsx
├── posts_.$postId.edit.tsx
Die folgende Tabelle zeigt, welche Komponente basierend auf der URL gerendert wird.
| URL-Pfad | Komponente |
|---|---|
| /posts | <Posts> |
| /posts/123 | <Posts><Post postId="123"> |
| /posts/123/edit | <PostEditor postId="123"> |
Dateien und Ordner können von der Routengenerierung ausgeschlossen werden, indem ein - Präfix an den Dateinamen angehängt wird. Dies gibt Ihnen die Möglichkeit, Logik in den Routenverzeichnissen zu lokalisieren.
Betrachten Sie den folgenden Routenbaum.
routes/
├── posts.tsx
├── -posts-table.tsx // 👈🏼 ignored
├── -components/ // 👈🏼 ignored
│ ├── header.tsx // 👈🏼 ignored
│ ├── footer.tsx // 👈🏼 ignored
│ ├── ...
routes/
├── posts.tsx
├── -posts-table.tsx // 👈🏼 ignored
├── -components/ // 👈🏼 ignored
│ ├── header.tsx // 👈🏼 ignored
│ ├── footer.tsx // 👈🏼 ignored
│ ├── ...
Wir können aus den ausgeschlossenen Dateien in unsere Posts-Route importieren.
import { createFileRoute } from '@tanstack/react-router'
import { PostsTable } from './-posts-table'
import { PostsHeader } from './-components/header'
import { PostsFooter } from './-components/footer'
export const Route = createFileRoute('/posts')({
loader: () => fetchPosts(),
component: PostComponent,
})
function PostComponent() {
const posts = Route.useLoaderData()
return (
<div>
<PostsHeader />
<PostsTable posts={posts} />
<PostsFooter />
</div>
)
}
import { createFileRoute } from '@tanstack/react-router'
import { PostsTable } from './-posts-table'
import { PostsHeader } from './-components/header'
import { PostsFooter } from './-components/footer'
export const Route = createFileRoute('/posts')({
loader: () => fetchPosts(),
component: PostComponent,
})
function PostComponent() {
const posts = Route.useLoaderData()
return (
<div>
<PostsHeader />
<PostsTable posts={posts} />
<PostsFooter />
</div>
)
}
Die ausgeschlossenen Dateien werden nicht zu routeTree.gen.ts hinzugefügt.
Pflose Routengruppen-Verzeichnisse verwenden () als Möglichkeit, Routendateien zusammenzufassen, unabhängig von ihrem Pfad. Sie sind rein organisatorisch und beeinflussen den Routenbaum oder den Komponentenbaum in keiner Weise.
routes/
├── index.tsx
├── (app)/
│ ├── dashboard.tsx
│ ├── settings.tsx
│ ├── users.tsx
├── (auth)/
│ ├── login.tsx
│ ├── register.tsx
routes/
├── index.tsx
├── (app)/
│ ├── dashboard.tsx
│ ├── settings.tsx
│ ├── users.tsx
├── (auth)/
│ ├── login.tsx
│ ├── register.tsx
Im obigen Beispiel sind die Verzeichnisse app und auth rein organisatorisch und beeinflussen den Routenbaum oder den Komponentenbaum in keiner Weise. Sie werden verwendet, um zusammengehörige Routen für eine einfachere Navigation und Organisation zu gruppieren.
Die folgende Tabelle zeigt, welche Komponente basierend auf der URL gerendert wird.
| URL-Pfad | Komponente |
|---|---|
| / | <Index> |
| /dashboard | <Dashboard> |
| /settings | <Settings> |
| /users | <Users> |
| /login | <Login> |
| /register | <Register> |
Wie Sie sehen können, sind die Verzeichnisse app und auth rein organisatorisch und beeinflussen den Routenbaum oder den Komponentenbaum in keiner Weise.
Ihre wöchentliche Dosis JavaScript-Nachrichten. Jeden Montag kostenlos an über 100.000 Entwickler geliefert.