loadersloader-Parameterloaders konsumierenloaderDeps zum Zugreifen auf SuchparameterstaleTime zur Steuerung, wie lange Daten als frisch geltenshouldReload und gcTime zum Opt-out von der ZwischenspeicherungrouteOptions.loaderDepspreload-FlagsrouteOptions.onErrorrouteOptions.onCatchrouteOptions.errorComponentErrorComponentDas Laden von Daten ist ein häufiges Anliegen für Webanwendungen und steht in Beziehung zum Routing. Beim Laden einer Seite für Ihre App ist es ideal, wenn alle asynchronen Anforderungen der Seite so früh wie möglich und parallel abgerufen und erfüllt werden. Der Router ist der beste Ort, um diese asynchronen Abhängigkeiten zu koordinieren, da er normalerweise der einzige Ort in Ihrer App ist, der weiß, wohin sich Benutzer bewegen, bevor Inhalte gerendert werden.
Sie sind vielleicht vertraut mit getServerSideProps aus Next.js oder loadern aus Remix/React-Router. TanStack Router bietet ähnliche Funktionalität zum Vorladen/Laden von Assets pro Route parallel, was ein möglichst schnelles Rendern beim Abrufen über Suspense ermöglicht.
Über diese normalen Erwartungen eines Routers hinaus geht TanStack Router noch einen Schritt weiter und bietet **integrierte SWR-Zwischenspeicherung**, eine langfristige In-Memory-Zwischenspeicherungsschicht für Routen-Loader. Das bedeutet, dass Sie TanStack Router verwenden können, um Daten für Ihre Routen vorzuladen, damit diese sofort geladen werden, oder um Routendaten für zuvor besuchte Routen vorübergehend zu cachen, um sie später wiederzuverwenden.
Jedes Mal, wenn eine URL-/Verlaufsaktualisierung erkannt wird, führt der Router die folgende Sequenz aus
Es ist sehr wahrscheinlich, dass der Router-Cache von TanStack gut für die meisten kleinen bis mittleren Anwendungen geeignet ist, aber es ist wichtig, die Kompromisse zu verstehen, die sich aus der Verwendung im Vergleich zu einer robusteren Caching-Lösung wie TanStack Query ergeben.
Vorteile des TanStack Router-Caches
Nachteile des TanStack Router-Caches
Tipp
Wenn Sie sofort wissen, dass Sie etwas Robusteres wie TanStack Query verwenden möchten oder müssen, springen Sie zum Leitfaden External Data Loading.
Der Router-Cache ist integriert und so einfach wie die Rückgabe von Daten aus der loader-Funktion einer beliebigen Route. Lassen Sie uns lernen, wie!
loadersRouten-loader-Funktionen werden aufgerufen, wenn ein Routen-Match geladen wird. Sie werden mit einem einzigen Parameter aufgerufen, der ein Objekt mit vielen hilfreichen Eigenschaften enthält. Wir werden diese gleich besprechen, aber zuerst sehen wir uns ein Beispiel für eine Routen-loader-Funktion an.
// routes/posts.tsx
export const Route = createFileRoute('/posts')({
loader: () => fetchPosts(),
})
// routes/posts.tsx
export const Route = createFileRoute('/posts')({
loader: () => fetchPosts(),
})
Die loader-Funktion empfängt ein einzelnes Objekt mit den folgenden Eigenschaften
Mit diesen Parametern können wir viele coole Dinge tun, aber zuerst schauen wir uns an, wie wir sie steuern und wann die loader-Funktion aufgerufen wird.
loaders konsumierenUm Daten aus einem loader zu konsumieren, verwenden Sie den Hook useLoaderData, der in Ihrem Route-Objekt definiert ist.
const posts = Route.useLoaderData()
const posts = Route.useLoaderData()
Wenn Sie keinen direkten Zugriff auf Ihr Routenobjekt haben (d. h. Sie befinden sich tief im Komponententeilbaum der aktuellen Route), können Sie getRouteApi verwenden, um auf denselben Hook (sowie die anderen Hooks im Route-Objekt) zuzugreifen. Dies sollte dem Importieren des Route-Objekts vorgezogen werden, da dies wahrscheinlich zu zirkulären Abhängigkeiten führen würde.
import { getRouteApi } from '@tanstack/solid-router'
// in your component
const routeApi = getRouteApi('/posts')
const data = routeApi.useLoaderData()
import { getRouteApi } from '@tanstack/solid-router'
// in your component
const routeApi = getRouteApi('/posts')
const data = routeApi.useLoaderData()
TanStack Router bietet eine integrierte Stale-While-Revalidate-Zwischenspeicherungsschicht für Routen-Loader, die auf den Abhängigkeiten einer Route basiert
Anhand dieser Abhängigkeiten als Schlüssel speichert TanStack Router die von der loader-Funktion einer Route zurückgegebenen Daten und verwendet sie, um nachfolgende Anfragen für denselben Routen-Match zu erfüllen. Das bedeutet, dass, wenn die Daten einer Route bereits im Cache sind, sie sofort zurückgegeben werden und **möglicherweise** im Hintergrund neu abgerufen werden, abhängig von der "Frische" der Daten.
Um Router-Abhängigkeiten und "Frische" zu steuern, bietet TanStack Router eine Fülle von Optionen zur Steuerung des Schlüssel- und Caching-Verhaltens Ihrer Routen-Loader. Lassen Sie uns diese in der Reihenfolge betrachten, in der Sie sie am wahrscheinlichsten verwenden werden.
staleTime verwendet.**Stellen Sie sich eine /posts-Route vor, die eine Paginierung über Suchparameter offset und limit unterstützt. Damit der Cache diese Daten eindeutig speichern kann, müssen wir über die Funktion loaderDeps auf diese Suchparameter zugreifen. Indem wir sie explizit identifizieren, werden die einzelnen Routen-Matches für /posts mit unterschiedlichen offset und limit nicht vermischt!
Sobald wir diese Abhängigkeiten eingerichtet haben, wird die Route immer neu geladen, wenn sich die Abhängigkeiten ändern.
// /routes/posts.tsx
export const Route = createFileRoute('/posts')({
loaderDeps: ({ search: { offset, limit } }) => ({ offset, limit }),
loader: ({ deps: { offset, limit } }) =>
fetchPosts({
offset,
limit,
}),
})
// /routes/posts.tsx
export const Route = createFileRoute('/posts')({
loaderDeps: ({ search: { offset, limit } }) => ({ offset, limit }),
loader: ({ deps: { offset, limit } }) =>
fetchPosts({
offset,
limit,
}),
})
Standardmäßig ist die staleTime für Navigationen auf 0 ms (und 30 Sekunden für Vorladungen) eingestellt, was bedeutet, dass die Daten der Route immer als veraltet gelten und immer im Hintergrund neu geladen werden, wenn die Route übereinstimmt und zu ihr navigiert wird.
Dies ist eine gute Standardeinstellung für die meisten Anwendungsfälle, aber Sie stellen möglicherweise fest, dass einige Routendaten statischer oder potenziell teuer zu laden sind. In diesen Fällen können Sie die Option staleTime verwenden, um zu steuern, wie lange die Daten der Route für Navigationen als frisch gelten. Sehen wir uns ein Beispiel an.
// /routes/posts.tsx
export const Route = createFileRoute('/posts')({
loader: () => fetchPosts(),
// Consider the route's data fresh for 10 seconds
staleTime: 10_000,
})
// /routes/posts.tsx
export const Route = createFileRoute('/posts')({
loader: () => fetchPosts(),
// Consider the route's data fresh for 10 seconds
staleTime: 10_000,
})
Durch die Übergabe von 10_000 an die Option staleTime teilen wir dem Router mit, die Daten der Route für 10 Sekunden als frisch zu betrachten. Das bedeutet, wenn der Benutzer innerhalb von 10 Sekunden nach dem letzten Loader-Ergebnis von /about zu /posts navigiert, werden die Daten der Route nicht neu geladen. Wenn der Benutzer dann nach 10 Sekunden von /about zu /posts navigiert, werden die Daten der Route **im Hintergrund** neu geladen.
Um die Stale-While-Revalidate-Zwischenspeicherung für eine Route zu deaktivieren, setzen Sie die Option staleTime auf Infinity.
// /routes/posts.tsx
export const Route = createFileRoute('/posts')({
loader: () => fetchPosts(),
staleTime: Infinity,
})
// /routes/posts.tsx
export const Route = createFileRoute('/posts')({
loader: () => fetchPosts(),
staleTime: Infinity,
})
Sie können dies sogar für alle Routen deaktivieren, indem Sie die Option defaultStaleTime im Router setzen.
const router = createRouter({
routeTree,
defaultStaleTime: Infinity,
})
const router = createRouter({
routeTree,
defaultStaleTime: Infinity,
})
Ähnlich wie die Standardfunktionalität von Remix möchten Sie vielleicht eine Route so konfigurieren, dass sie nur beim Eintritt oder bei Änderung kritischer Loader-Abhängigkeiten geladen wird. Sie können dies tun, indem Sie die Option gcTime in Kombination mit der Option shouldReload verwenden, die entweder einen boolean oder eine Funktion akzeptiert, die die gleichen beforeLoad- und loaderContext-Parameter empfängt und einen booleschen Wert zurückgibt, der angibt, ob die Route neu geladen werden soll.
// /routes/posts.tsx
export const Route = createFileRoute('/posts')({
loaderDeps: ({ search: { offset, limit } }) => ({ offset, limit }),
loader: ({ deps }) => fetchPosts(deps),
// Do not cache this route's data after it's unloaded
gcTime: 0,
// Only reload the route when the user navigates to it or when deps change
shouldReload: false,
})
// /routes/posts.tsx
export const Route = createFileRoute('/posts')({
loaderDeps: ({ search: { offset, limit } }) => ({ offset, limit }),
loader: ({ deps }) => fetchPosts(deps),
// Do not cache this route's data after it's unloaded
gcTime: 0,
// Only reload the route when the user navigates to it or when deps change
shouldReload: false,
})
Auch wenn Sie sich von der kurzfristigen Zwischenspeicherung für Ihre Routendaten abmelden, können Sie dennoch von der Vorladung profitieren! Mit der obigen Konfiguration funktioniert die Vorladung weiterhin "einfach" mit der Standard-preloadGcTime. Das bedeutet, wenn eine Route vorgeladen und dann navigiert wird, gelten die Daten der Route als frisch und werden nicht neu geladen.
Um sich von der Vorladung abzumelden, schalten Sie sie nicht über die Optionen routerOptions.defaultPreload oder routeOptions.preload ein.
Wir behandeln diesen Anwendungsfall auf der Seite External Data Loading, aber wenn Sie einen externen Cache wie TanStack Query verwenden möchten, können Sie dies tun, indem Sie alle Loader-Ereignisse an Ihren externen Cache weiterleiten. Solange Sie die Standardeinstellungen verwenden, besteht die einzige Änderung, die Sie vornehmen müssen, darin, die Option defaultPreloadStaleTime für den Router auf 0 zu setzen.
const router = createRouter({
routeTree,
defaultPreloadStaleTime: 0,
})
const router = createRouter({
routeTree,
defaultPreloadStaleTime: 0,
})
Dies stellt sicher, dass jedes Vorlade-, Lade- und Neuladeereignis Ihre loader-Funktionen auslöst, die dann von Ihrem externen Cache behandelt und dedupliziert werden können.
Das Argument context, das an die loader-Funktion übergeben wird, ist ein Objekt, das eine zusammengeführte Vereinigung von
Ganz oben im Router können Sie einen initialen Kontext über die Option context an den Router übergeben. Dieser Kontext ist für alle Routen im Router verfügbar und wird von jeder Route beim Abgleichen kopiert und erweitert. Dies geschieht, indem ein Kontext über die Option beforeLoad an eine Route übergeben wird. Dieser Kontext ist für alle untergeordneten Routen der Route verfügbar. Der resultierende Kontext ist für die loader-Funktion der Route verfügbar.
In diesem Beispiel erstellen wir eine Funktion in unserem Routenkontext, um Beiträge abzurufen, und verwenden sie dann in unserer loader-Funktion.
🧠 Kontext ist ein mächtiges Werkzeug für Dependency Injection. Sie können ihn verwenden, um Services, Hooks und andere Objekte in Ihren Router und Ihre Routen zu injizieren. Sie können auch Daten über den Routenbaum an jeder Route additiv weitergeben, indem Sie die Option beforeLoad einer Route verwenden.
export const fetchPosts = async () => {
const res = await fetch(`/api/posts?page=${pageIndex}`)
if (!res.ok) throw new Error('Failed to fetch posts')
return res.json()
}
export const fetchPosts = async () => {
const res = await fetch(`/api/posts?page=${pageIndex}`)
if (!res.ok) throw new Error('Failed to fetch posts')
return res.json()
}
import { createRootRouteWithContext } from '@tanstack/solid-router'
// Create a root route using the createRootRouteWithContext<{...}>() function and pass it whatever types you would like to be available in your router context.
export const Route = createRootRouteWithContext<{
fetchPosts: typeof fetchPosts
}>()() // NOTE: the double call is on purpose, since createRootRouteWithContext is a factory ;)
import { createRootRouteWithContext } from '@tanstack/solid-router'
// Create a root route using the createRootRouteWithContext<{...}>() function and pass it whatever types you would like to be available in your router context.
export const Route = createRootRouteWithContext<{
fetchPosts: typeof fetchPosts
}>()() // NOTE: the double call is on purpose, since createRootRouteWithContext is a factory ;)
import { createFileRoute } from '@tanstack/solid-router'
// Notice how our postsRoute references context to get our fetchPosts function
// This can be a powerful tool for dependency injection across your router
// and routes.
export const Route = createFileRoute('/posts')({
loader: ({ context: { fetchPosts } }) => fetchPosts(),
})
import { createFileRoute } from '@tanstack/solid-router'
// Notice how our postsRoute references context to get our fetchPosts function
// This can be a powerful tool for dependency injection across your router
// and routes.
export const Route = createFileRoute('/posts')({
loader: ({ context: { fetchPosts } }) => fetchPosts(),
})
import { routeTree } from './routeTree.gen'
// Use your routerContext to create a new router
// This will require that you fullfil the type requirements of the routerContext
const router = createRouter({
routeTree,
context: {
// Supply the fetchPosts function to the router context
fetchPosts,
},
})
import { routeTree } from './routeTree.gen'
// Use your routerContext to create a new router
// This will require that you fullfil the type requirements of the routerContext
const router = createRouter({
routeTree,
context: {
// Supply the fetchPosts function to the router context
fetchPosts,
},
})
Um Pfadparameter in Ihrer loader-Funktion zu verwenden, greifen Sie über die Eigenschaft params auf die Parameter der Funktion zu. Hier ist ein Beispiel.
// routes/posts.$postId.tsx
export const Route = createFileRoute('/posts/$postId')({
loader: ({ params: { postId } }) => fetchPostById(postId),
})
// routes/posts.$postId.tsx
export const Route = createFileRoute('/posts/$postId')({
loader: ({ params: { postId } }) => fetchPostById(postId),
})
Das Heruntergeben eines globalen Kontexts an Ihren Router ist großartig, aber was, wenn Sie einen Kontext bereitstellen möchten, der für eine bestimmte Route spezifisch ist? Hier kommt die Option beforeLoad ins Spiel. Die Option beforeLoad ist eine Funktion, die unmittelbar vor dem Versuch, eine Route zu laden, ausgeführt wird und die gleichen Parameter wie loader empfängt. Neben ihrer Fähigkeit, potenzielle Übereinstimmungen umzuleiten, Loader-Anfragen zu blockieren usw., kann sie auch ein Objekt zurückgeben, das in den Kontext der Route integriert wird. Sehen wir uns ein Beispiel an, bei dem wir einige Daten über die Option beforeLoad in unseren Routenkontext injizieren.
// /routes/posts.tsx
import { createFileRoute } from '@tanstack/solid-router'
export const Route = createFileRoute('/posts')({
// Pass the fetchPosts function to the route context
beforeLoad: () => ({
fetchPosts: () => console.info('foo'),
}),
loader: ({ context: { fetchPosts } }) => {
console.info(fetchPosts()) // 'foo'
// ...
},
})
// /routes/posts.tsx
import { createFileRoute } from '@tanstack/solid-router'
export const Route = createFileRoute('/posts')({
// Pass the fetchPosts function to the route context
beforeLoad: () => ({
fetchPosts: () => console.info('foo'),
}),
loader: ({ context: { fetchPosts } }) => {
console.info(fetchPosts()) // 'foo'
// ...
},
})
❓ Aber warte mal, Tanner... wo sind meine Suchparameter?
Sie fragen sich vielleicht, warum search nicht direkt in den Parametern der loader-Funktion verfügbar ist. Wir haben es bewusst so gestaltet, um Ihnen zum Erfolg zu verhelfen. Lassen Sie uns sehen, warum.
// /routes/users.user.tsx
export const Route = createFileRoute('/users/user')({
validateSearch: (search) =>
search as {
userId: string
},
loaderDeps: ({ search: { userId } }) => ({
userId,
}),
loader: async ({ deps: { userId } }) => getUser(userId),
})
// /routes/users.user.tsx
export const Route = createFileRoute('/users/user')({
validateSearch: (search) =>
search as {
userId: string
},
loaderDeps: ({ search: { userId } }) => ({
userId,
}),
loader: async ({ deps: { userId } }) => getUser(userId),
})
// /routes/posts.tsx
export const Route = createFileRoute('/posts')({
// Use zod to validate and parse the search params
validateSearch: z.object({
offset: z.number().int().nonnegative().catch(0),
}),
// Pass the offset to your loader deps via the loaderDeps function
loaderDeps: ({ search: { offset } }) => ({ offset }),
// Use the offset from context in the loader function
loader: async ({ deps: { offset } }) =>
fetchPosts({
offset,
}),
})
// /routes/posts.tsx
export const Route = createFileRoute('/posts')({
// Use zod to validate and parse the search params
validateSearch: z.object({
offset: z.number().int().nonnegative().catch(0),
}),
// Pass the offset to your loader deps via the loaderDeps function
loaderDeps: ({ search: { offset } }) => ({ offset }),
// Use the offset from context in the loader function
loader: async ({ deps: { offset } }) =>
fetchPosts({
offset,
}),
})
Die Eigenschaft abortController der loader-Funktion ist ein AbortController. Sein Signal wird abgebrochen, wenn die Route entladen wird oder wenn der loader-Aufruf veraltet ist. Dies ist nützlich zum Abbrechen von Netzwerkanfragen, wenn die Route entladen wird oder wenn sich die Parameter der Route ändern. Hier ist ein Beispiel, das es mit einem Fetch-Aufruf verwendet.
// routes/posts.tsx
export const Route = createFileRoute('/posts')({
loader: ({ abortController }) =>
fetchPosts({
// Pass this to an underlying fetch call or anything that supports signals
signal: abortController.signal,
}),
})
// routes/posts.tsx
export const Route = createFileRoute('/posts')({
loader: ({ abortController }) =>
fetchPosts({
// Pass this to an underlying fetch call or anything that supports signals
signal: abortController.signal,
}),
})
Die Eigenschaft preload der loader-Funktion ist ein Boolean, der true ist, wenn die Route vorgeladen anstatt geladen wird. Einige Datenladebibliotheken behandeln die Vorladung möglicherweise anders als ein Standard-Fetch, sodass Sie preload an Ihre Datenladebibliothek übergeben oder sie verwenden möchten, um die entsprechende Datenladelogik auszuführen.
// routes/posts.tsx
export const Route = createFileRoute('/posts')({
loader: async ({ preload }) =>
fetchPosts({
maxAge: preload ? 10_000 : 0, // Preloads should hang around a bit longer
}),
})
// routes/posts.tsx
export const Route = createFileRoute('/posts')({
loader: async ({ preload }) =>
fetchPosts({
maxAge: preload ? 10_000 : 0, // Preloads should hang around a bit longer
}),
})
Idealerweise können die meisten Routen-Loader ihre Daten innerhalb eines kurzen Moments auflösen, wodurch die Notwendigkeit entfällt, einen Platzhalter-Spinner zu rendern, und sich einfach auf Suspense verlassen, um die nächste Route zu rendern, wenn sie vollständig bereit ist. Wenn kritische Daten, die zum Rendern der Komponente einer Route benötigt werden, jedoch langsam sind, haben Sie 2 Optionen
Standardmäßig zeigt TanStack Router eine ausstehende Komponente für Loader an, die länger als 1 Sekunde zur Auflösung benötigen. Dies ist ein optimistischer Schwellenwert, der konfiguriert werden kann über
Wenn der Schwellenwert für die ausstehende Zeit überschritten wird, rendert der Router die Option pendingComponent der Route, falls konfiguriert.
Wenn Sie eine ausstehende Komponente verwenden, ist das Letzte, was Sie wollen, dass Ihr ausstehender Zeit-Schwellenwert erreicht wird und Ihre Daten sofort danach aufgelöst werden, was zu einem abrupten Aufblitzen Ihrer ausstehenden Komponente führt. Um dies zu vermeiden, **zeigt TanStack Router standardmäßig Ihre ausstehende Komponente für mindestens 500 ms an**. Dies ist ein optimistischer Schwellenwert, der konfiguriert werden kann über
TanStack Router bietet mehrere Möglichkeiten, Fehler zu behandeln, die während des Routenladens auftreten. Lassen Sie uns diese betrachten.
Die Option routeOptions.onError ist eine Funktion, die aufgerufen wird, wenn während des Routenladens ein Fehler auftritt.
// routes/posts.tsx
export const Route = createFileRoute('/posts')({
loader: () => fetchPosts(),
onError: ({ error }) => {
// Log the error
console.error(error)
},
})
// routes/posts.tsx
export const Route = createFileRoute('/posts')({
loader: () => fetchPosts(),
onError: ({ error }) => {
// Log the error
console.error(error)
},
})
Die Option routeOptions.onCatch ist eine Funktion, die aufgerufen wird, wenn ein Fehler vom CatchBoundary des Routers abgefangen wurde.
// routes/posts.tsx
export const Route = createFileRoute('/posts')({
onCatch: ({ error, errorInfo }) => {
// Log the error
console.error(error)
},
})
// routes/posts.tsx
export const Route = createFileRoute('/posts')({
onCatch: ({ error, errorInfo }) => {
// Log the error
console.error(error)
},
})
Die Option routeOptions.errorComponent ist eine Komponente, die gerendert wird, wenn während des Routenladens oder Rendering-Lebenszyklus ein Fehler auftritt. Sie wird mit den folgenden Props gerendert
// routes/posts.tsx
export const Route = createFileRoute('/posts')({
loader: () => fetchPosts(),
errorComponent: ({ error }) => {
// Render an error message
return <div>{error.message}</div>
},
})
// routes/posts.tsx
export const Route = createFileRoute('/posts')({
loader: () => fetchPosts(),
errorComponent: ({ error }) => {
// Render an error message
return <div>{error.message}</div>
},
})
Die Funktion reset kann verwendet werden, um dem Benutzer zu ermöglichen, das erneute Rendern der normalen Kinder des Fehlergrenzbereichs zu versuchen.
// routes/posts.tsx
export const Route = createFileRoute('/posts')({
loader: () => fetchPosts(),
errorComponent: ({ error, reset }) => {
return (
<div>
{error.message}
<button
onClick={() => {
// Reset the router error boundary
reset()
}}
>
retry
</button>
</div>
)
},
})
// routes/posts.tsx
export const Route = createFileRoute('/posts')({
loader: () => fetchPosts(),
errorComponent: ({ error, reset }) => {
return (
<div>
{error.message}
<button
onClick={() => {
// Reset the router error boundary
reset()
}}
>
retry
</button>
</div>
)
},
})
Wenn der Fehler das Ergebnis eines Routenladens war, sollten Sie stattdessen router.invalidate() aufrufen, was sowohl ein Router-Neuladen als auch ein Zurücksetzen des Fehlergrenzbereichs koordiniert.
// routes/posts.tsx
export const Route = createFileRoute('/posts')({
loader: () => fetchPosts(),
errorComponent: ({ error, reset }) => {
const router = useRouter()
return (
<div>
{error.message}
<button
onClick={() => {
// Invalidate the route to reload the loader, which will also reset the error boundary
router.invalidate()
}}
>
retry
</button>
</div>
)
},
})
// routes/posts.tsx
export const Route = createFileRoute('/posts')({
loader: () => fetchPosts(),
errorComponent: ({ error, reset }) => {
const router = useRouter()
return (
<div>
{error.message}
<button
onClick={() => {
// Invalidate the route to reload the loader, which will also reset the error boundary
router.invalidate()
}}
>
retry
</button>
</div>
)
},
})
ErrorComponentTanStack Router bietet eine Standard-ErrorComponent, die gerendert wird, wenn während des Routenladens oder Rendering-Lebenszyklus ein Fehler auftritt. Wenn Sie sich entscheiden, die Fehlerkomponenten Ihrer Routen zu überschreiben, ist es dennoch ratsam, immer auf die Darstellung nicht abgefangener Fehler mit der Standard-ErrorComponent zurückzufallen.
// routes/posts.tsx
import { createFileRoute, ErrorComponent } from '@tanstack/solid-router'
export const Route = createFileRoute('/posts')({
loader: () => fetchPosts(),
errorComponent: ({ error }) => {
if (error instanceof MyCustomError) {
// Render a custom error message
return <div>{error.message}</div>
}
// Fallback to the default ErrorComponent
return <ErrorComponent error={error} />
},
})
// routes/posts.tsx
import { createFileRoute, ErrorComponent } from '@tanstack/solid-router'
export const Route = createFileRoute('/posts')({
loader: () => fetchPosts(),
errorComponent: ({ error }) => {
if (error instanceof MyCustomError) {
// Render a custom error message
return <div>{error.message}</div>
}
// Fallback to the default ErrorComponent
return <ErrorComponent error={error} />
},
})
Ihre wöchentliche Dosis JavaScript-Nachrichten. Jeden Montag kostenlos an über 100.000 Entwickler geliefert.