# Suspense

> 

> [!WARNING] Deprecated
> The classic React Query integration (`@trpc/react-query`) only gets bug fixes, and will be removed in the next major version of tRPC. New projects should use the [TanStack React Query integration](https://trpc.io/docs/client/tanstack-react-query.md) (`@trpc/tanstack-react-query`). To move an existing project, follow the [migration guide](https://trpc.io/docs/client/tanstack-react-query/migrating.md).


> [!NOTE] Info
>
> - Ensure you're on the latest version of React
> - If you use suspense with [tRPC's _automatic_ SSR in Next.js](https://trpc.io/docs/client/nextjs/pages-router/ssr.md), the full page will crash on the server if a query fails, even if you have an `<ErrorBoundary />`


## Usage

> [!TIP]
>
> `useSuspenseQuery` & `useSuspenseInfiniteQuery` both return a `[data, query]`-_tuple_, to make it easy to directly use your data and renaming the variable to something descriptive


### `useSuspenseQuery()`

```tsx
import { trpc } from '../utils/trpc';

function PostView() {
  const [post, postQuery] = trpc.post.byId.useSuspenseQuery({ id: '1' });
  // const post: {
  //     id: string;
  //     title: string;
  // }

  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 <>{/* ... */}</>;
}
```

### `useSuspenseQueries()`

Suspense equivalent of [`useQueries()`](https://trpc.io/docs/client/react/useQueries.md).

```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 <>{/* [...] */}</>;
};
```

## Prefetching

The performance of suspense queries can be improved by prefetching the query data before the Suspense component is rendered (this is sometimes called ["render-as-you-fetch"](https://tanstack.com/query/v5/docs/framework/react/guides/suspense#fetch-on-render-vs-render-as-you-fetch)).

> [!NOTE]
>
> - Prefetching and the render-as-you-fetch model are very dependent on the framework and router you are using. We recommend reading your frameworks router docs along with the [@tanstack/react-query docs](https://tanstack.com/query/v5/docs/react/guides/prefetching) to understand how to implement these patterns.
> - If you are using Next.js please look at the docs on [Server-Side Helpers](https://trpc.io/docs/client/nextjs/pages-router/server-side-helpers.md) to implement server-side prefetching.


### Route-level prefetching

```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 });
```

### Component-level prefetching with `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>
  );
}
```

### Component-level prefetching with `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>
  );
}
```
