Aller au contenu principal
Version : 11.x

Suspense

Traduction Bêta Non Officielle

Cette page a été traduite par PageTurner AI (bêta). Non approuvée officiellement par le projet. Vous avez trouvé une erreur ? Signaler un problème →

info
  • Assurez-vous d'utiliser la dernière version de React
  • Si vous utilisez Suspense avec le SSR automatique de tRPC dans Next.js, la page entière plantera sur le serveur en cas d'échec d'une requête, même avec un <ErrorBoundary />

Utilisation

astuce

useSuspenseQuery et useSuspenseInfiniteQuery retournent toutes deux un [data, query]-tuple, facilitant l'utilisation directe des données et le renommage descriptif des variables

useSuspenseQuery()

tsx
import { trpc } from '../utils/trpc';
 
function PostView() {
const [post, postQuery] = trpc.post.byId.useSuspenseQuery({ id: '1' });
 
return <>{/* ... */}</>;
}
tsx
import { trpc } from '../utils/trpc';
 
function PostView() {
const [post, postQuery] = trpc.post.byId.useSuspenseQuery({ id: '1' });
 
return <>{/* ... */}</>;
}

useSuspenseInfiniteQuery()

tsx
import { trpc } from '../utils/trpc';
import type { PostPage } from '../server';
 
function PostView() {
const [{ pages }, allPostsQuery] = trpc.post.all.useSuspenseInfiniteQuery(
{},
{
getNextPageParam(lastPage: PostPage) {
return lastPage.nextCursor;
},
initialCursor: '',
},
);
 
const { isFetching, isFetchingNextPage, fetchNextPage, hasNextPage } =
allPostsQuery;
 
return <>{/* ... */}</>;
}
tsx
import { trpc } from '../utils/trpc';
import type { PostPage } from '../server';
 
function PostView() {
const [{ pages }, allPostsQuery] = trpc.post.all.useSuspenseInfiniteQuery(
{},
{
getNextPageParam(lastPage: PostPage) {
return lastPage.nextCursor;
},
initialCursor: '',
},
);
 
const { isFetching, isFetchingNextPage, fetchNextPage, hasNextPage } =
allPostsQuery;
 
return <>{/* ... */}</>;
}

useSuspenseQueries()

Équivalent Suspense de useQueries().

tsx
import { trpc } from '../utils/trpc';
 
const Component = (props: { postIds: string[] }) => {
const [posts, postQueries] = trpc.useSuspenseQueries((t) =>
props.postIds.map((id) => t.post.byId({ id })),
);
 
return <>{/* [...] */}</>;
};
tsx
import { trpc } from '../utils/trpc';
 
const Component = (props: { postIds: string[] }) => {
const [posts, postQueries] = trpc.useSuspenseQueries((t) =>
props.postIds.map((id) => t.post.byId({ id })),
);
 
return <>{/* [...] */}</>;
};

Préchargement

Les performances des requêtes Suspense peuvent être améliorées en préchargeant les données avant le rendu du composant Suspense (approche parfois appelée "render-as-you-fetch").

note
  • Le préchargement et le modèle render-as-you-fetch dépendent fortement du framework et du routeur utilisés. Consultez la documentation du routeur de votre framework ainsi que la documentation @tanstack/react-query pour comprendre leur implémentation.
  • Pour Next.js, référez-vous à la documentation sur les Server-Side Helpers pour le préchargement côté serveur.

Préchargement au niveau des routes

tsx
import { createTRPCQueryUtils } from '@trpc/react-query';
import { createTRPCClient, httpBatchLink } from '@trpc/client';
import { QueryClient } from '@tanstack/react-query';
import type { AppRouter } from './server';
 
const queryClient = new QueryClient();
const trpcClient = createTRPCClient<AppRouter>({ links: [httpBatchLink({ url: 'http://localhost:3000' })] });
const utils = createTRPCQueryUtils({ queryClient, client: trpcClient });
 
// tanstack router/ react router loader
const loader = async (params: { id: string }) =>
utils.post.byId.ensureData({ id: params.id });
tsx
import { createTRPCQueryUtils } from '@trpc/react-query';
import { createTRPCClient, httpBatchLink } from '@trpc/client';
import { QueryClient } from '@tanstack/react-query';
import type { AppRouter } from './server';
 
const queryClient = new QueryClient();
const trpcClient = createTRPCClient<AppRouter>({ links: [httpBatchLink({ url: 'http://localhost:3000' })] });
const utils = createTRPCQueryUtils({ queryClient, client: trpcClient });
 
// tanstack router/ react router loader
const loader = async (params: { id: string }) =>
utils.post.byId.ensureData({ id: params.id });

Préchargement au niveau des composants avec usePrefetchQuery

tsx
import React, { Suspense } from 'react';
import { trpc } from '../utils/trpc';
 
function PostView(props: { postId: string }) {
return <></>;
}
 
function PostViewPage(props: { postId: string }) {
trpc.post.byId.usePrefetchQuery({ id: props.postId });
 
return (
<Suspense>
<PostView postId={props.postId} />
</Suspense>
);
}
tsx
import React, { Suspense } from 'react';
import { trpc } from '../utils/trpc';
 
function PostView(props: { postId: string }) {
return <></>;
}
 
function PostViewPage(props: { postId: string }) {
trpc.post.byId.usePrefetchQuery({ id: props.postId });
 
return (
<Suspense>
<PostView postId={props.postId} />
</Suspense>
);
}

Préchargement au niveau des composants avec usePrefetchInfiniteQuery

tsx
import React, { Suspense } from 'react';
import { trpc } from '../utils/trpc';
import type { PostPage } from '../server';
 
function PostView(props: { postId: string }) {
return <></>;
}
 
function PostViewPage(props: { postId: string }) {
trpc.post.all.usePrefetchInfiniteQuery(
{},
{
getNextPageParam(lastPage: PostPage) {
return lastPage.nextCursor;
},
initialCursor: '',
},
);
 
return (
<Suspense>
<PostView postId={props.postId} />
</Suspense>
);
}
tsx
import React, { Suspense } from 'react';
import { trpc } from '../utils/trpc';
import type { PostPage } from '../server';
 
function PostView(props: { postId: string }) {
return <></>;
}
 
function PostViewPage(props: { postId: string }) {
trpc.post.all.usePrefetchInfiniteQuery(
{},
{
getNextPageParam(lastPage: PostPage) {
return lastPage.nextCursor;
},
initialCursor: '',
},
);
 
return (
<Suspense>
<PostView postId={props.postId} />
</Suspense>
);
}