Skip to content

Instantly share code, notes, and snippets.

@nilshartmann
Last active August 28, 2024 10:55
Show Gist options
  • Save nilshartmann/1d58affa21162fa7e014e1250fd738fa to your computer and use it in GitHub Desktop.
Save nilshartmann/1d58affa21162fa7e014e1250fd738fa to your computer and use it in GitHub Desktop.
async function loadArticle(articleId) { /* ... */ }
async function loadComments(articleId) { /* ... */ }
async function Page( {articleId} ) {
// Beide Requests starten parallel
const articlePromise = loadArticle(articleId);
const commentsPromise = loadComments(articleId);
return <React.Suspense fallback={<h1>Please wait, data is loading</h1>}>
<Article articlePromise={articlePromise} />
<CommentList commentsPromise={commentPromise} />
</React.Suspense>;
}
async function Article({articlePromise}) {
const article = await commentsPromise;
// Artikel rendern und zurück liefern
return <article><h1>{article.title}</h1></article>
}
async function CommentList({commentsPromise}) {
const comments = await commentsPromise;
// Kommentare rendern und zurück liefern
return <>...</>
}
async function loadArticle(articleId) { /* ... */ }
async function loadComments(articleId) { /* ... */ }
async function Page( {articleId} ) {
const articlePromise = loadArticle(articleId);
const commentsPromise = loadComments(articleId);
return <>
<React.Suspense fallback={<h1>Please wait, article is loading</h1>}>
<Article articlePromise={articlePromise} />
</React.Suspense>
<React.Suspense fallback={<h1>Please wait, comments are loading</h1>}>
<CommentList commentsPromise={commentPromise} />
</React.Suspense>
</>;
}
async function Article({articlePromise}) {
// unverändert
}
async function CommentList({commentsPromise}) {
// unverändert
}
async function loadArticle(articleId) { /* ... */ }
async function loadComments(articleId) { /* ... */ }
async function Page( {articleId} ) {
return <React.Suspense fallback={<h1>Please wait, article is loading</h1>}>
<ArticlePage article={articleId} />
</React.Suspense>
}
async function Article( {articleId} ) {
// Beide Requests starten parallel,
// aber hier wird direkt auf die Artikel gewartet
const commentsPromise = loadComments(articleId);
const articlePromise = await loadArticle(articleId);
return <>
<h1>{article.title}</h1>
{ /* ... Artikel rendern ... */ }
<React.Suspense fallback={<h1>Please wait, comments are loading</h1>}>
<CommentList commentsPromise={commentPromise} />
</React.Suspense>
</>;
}
async function CommentList({commentsPromise}) {
// unverändert
}
import { useQueryClient, useSuspenseQuery } from "@tanstack/react-query";
async function loadArticle(articleId) { /* ... */ }
async function loadComments(articleId) { /* ... */ }
function Page( {articleId} ) {
return <React.Suspense fallback={<h1>Please wait, article is loading</h1>}>
<ArticlePage article={articleId} />
</React.Suspense>
}
function Article( {articleId} ) {
// "ensureQueryData" startet den Comments-Query,
// ohne auf dessen Antwort zu warten
const queryClient = useQueryClient();
queryClient.ensureQueryData({
queryKey: ["blogpost", articleId, "comments"],
queryFn: () => loadComments(articleId),
});
// Das Rendern der Komponente wird erst
// fortgesetzt, wenn der folgende Query
// ausgeführt wurde
const { data: article } = useSuspenseQuery({
queryKey: ["blogpost", articleId],
queryFn: () => loadArticle(articleId),
});
return <>
<h1>{article.title}</h1>
{ /* ... Artikel rendern ... */ }
<React.Suspense fallback={<h1>Please wait, comments are loading</h1>}>
<CommentList articleId={articleId} />
</React.Suspense>
</>;
}
function CommentList( {articleId} ) {
const { data: comments } = useSuspenseQuery({
queryKey: ["blogpost", articleId, "comments"],
queryFn: () => loadComments(articleId),
});
// comments rendern
}
// Router-Konfiguration (Ausschnitt)
const router = createBrowserRouter([
{
path: "post/:articleId",
element: <Page />,
loader: articlePageLoader,
},
// ...
]);
//
export function articlePageLoader({ params }) {
const { articleId } = params;
return defer({
// beide Requests starten, aber nur auf die Artikel warten
commentsPromise: loadComments(params.articleId),
article: await loadArticle(params.articleId)
})
};
function Page() {
const { article, commentsPromise } = useLoaderData();
return <>
<h1>{article.title}</h1>
{ /* ... Artikel rendern ... */ }
<Suspense
fallback={<LoadingIndicator>Comments loading...</LoadingIndicator>}
>
<Await resolve={commentsPromise}>
<CommentList />
</Await>
</Suspense>
</>
);
}
function CommentList() {
const comments = useAsyncValue();
// Kommentare rendern
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment