# React Query Integration (Classic, deprecated)

> The classic React Query integration, which only gets bug fixes and will be removed in the next major version of tRPC

> [!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).


tRPC offers a first class integration with React. Under the hood this is simply a wrapper around the very popular [@tanstack/react-query](https://tanstack.com/query/latest), so we recommend that you familiarize yourself with React Query, as their docs go into much greater depth on its usage.

If you are using Next.js we recommend using [our integration with that](https://trpc.io/docs/client/nextjs.md) instead.

<details>
<summary>❓ Do I have to use an integration?</summary>

No! The integration is fully optional. You can use `@tanstack/react-query` using just a [vanilla tRPC client](https://trpc.io/docs/client/vanilla.md), although then you'll have to manually manage query keys and do not get the same level of DX as when using the integration package.

```ts title="utils/trpc.ts"
import { createTRPCClient, httpBatchLink } from '@trpc/client';
import type { AppRouter } from '../server';

export const trpc = createTRPCClient<AppRouter>({
  links: [httpBatchLink({ url: 'YOUR_API_URL' })],
});
```

```tsx title="components/PostList.tsx"
import { useQuery } from '@tanstack/react-query';
import { trpc } from '../utils/trpc';

function PostList() {
  const { data } = useQuery({
    queryKey: ['posts'],
    queryFn: () => trpc.post.list.query(),
  });
  data; // Post[]

  // ...
}
```

</details>

### The tRPC React Query Integration

This library enables usage directly within React components.

```tsx title="pages/IndexPage.tsx"
import { trpc } from '../utils/trpc';

export default function IndexPage() {
  const helloQuery = trpc.hello.useQuery({ name: 'Bob' });
  const goodbyeMutation = trpc.goodbye.useMutation();

  return (
    <div>
      <p>{helloQuery.data?.greeting}</p>

      <button onClick={() => goodbyeMutation.mutate()}>Say Goodbye</button>
    </div>
  );
}
```

### Differences to vanilla React Query

The wrapper abstracts some aspects of React Query for you:

- Query Keys - these are generated and managed by tRPC on your behalf, based on the procedure inputs you provide
  - If you need the query key which tRPC calculates, you can use [getQueryKey](https://trpc.io/docs/client/react/getQueryKey.md)
- Type safe by default - the types you provide in your tRPC Backend also drive the types of your React Query client, providing safety throughout your React app
