Skip to main content
Version: 11.x

TanStack React Query

与我们的 经典 React 查询集成 相比,此客户端更简单且更 TanStack Query 原生,为常见的 TanStack React Query 接口(如 QueryKeys、QueryOptions 和 MutationOptions)提供工厂。我们认为这是未来,并建议使用它而不是经典客户端 read the announcement post 来了解有关此更改的更多信息。

¥Compared to our classic React Query Integration this client is simpler and more TanStack Query-native, providing factories for common TanStack React Query interfaces like QueryKeys, QueryOptions, and MutationOptions. We think it's the future and recommend using this over the classic client, read the announcement post for more information about this change.

快速示例查询

¥Quick example query

tsx
import { useQuery } from '@tanstack/react-query';
import { useTRPC } from './trpc';
function Users() {
const trpc = useTRPC();
const greetingQuery = useQuery(trpc.greeting.queryOptions({ name: 'Jerry' }));
// greetingQuery.data === 'Hello Jerry'
}
tsx
import { useQuery } from '@tanstack/react-query';
import { useTRPC } from './trpc';
function Users() {
const trpc = useTRPC();
const greetingQuery = useQuery(trpc.greeting.queryOptions({ name: 'Jerry' }));
// greetingQuery.data === 'Hello Jerry'
}

用法

¥Usage

此客户端的理念是提供精简且类型安全的工厂,这些工厂可以与 Tanstack React Query 原生且类型安全地协同工作。这意味着只需遵循客户端给你的自动补齐,你就可以专注于仅使用 TanStack React Query 文档 提供的知识进行构建。

¥The philosophy of this client is to provide thin and type-safe factories which work natively and type-safely with Tanstack React Query. This means just by following the autocompletes the client gives you, you can focus on building just with the knowledge the TanStack React Query docs provide.

tsx
export default function Basics() {
const trpc = useTRPC();
const queryClient = useQueryClient();
// Create QueryOptions which can be passed to query hooks
const myQueryOptions = trpc.path.to.query.queryOptions({ /** inputs */ })
const myQuery = useQuery(myQueryOptions)
// or:
// useSuspenseQuery(myQueryOptions)
// useInfiniteQuery(myQueryOptions)
// Create MutationOptions which can be passed to useMutation
const myMutationOptions = trpc.path.to.mutation.mutationOptions()
const myMutation = useMutation(myMutationOptions)
// Create a QueryKey which can be used to manipulated many methods
// on TanStack's QueryClient in a type-safe manner
const myQueryKey = trpc.path.to.query.queryKey()
const invalidateMyQueryKey = () => {
queryClient.invalidateQueries({ queryKey: myQueryKey })
}
return (
// Your app here
)
}
tsx
export default function Basics() {
const trpc = useTRPC();
const queryClient = useQueryClient();
// Create QueryOptions which can be passed to query hooks
const myQueryOptions = trpc.path.to.query.queryOptions({ /** inputs */ })
const myQuery = useQuery(myQueryOptions)
// or:
// useSuspenseQuery(myQueryOptions)
// useInfiniteQuery(myQueryOptions)
// Create MutationOptions which can be passed to useMutation
const myMutationOptions = trpc.path.to.mutation.mutationOptions()
const myMutation = useMutation(myMutationOptions)
// Create a QueryKey which can be used to manipulated many methods
// on TanStack's QueryClient in a type-safe manner
const myQueryKey = trpc.path.to.query.queryKey()
const invalidateMyQueryKey = () => {
queryClient.invalidateQueries({ queryKey: myQueryKey })
}
return (
// Your app here
)
}

trpc 对象完全类型安全,将为 AppRouter 中的所有过程提供自动补齐功能。在代理的末尾,可以使用以下方法:

¥The trpc object is fully type-safe and will provide autocompletes for all the procedures in your AppRouter. At the end of the proxy, the following methods are available:

queryOptions - 查询数据

¥queryOptions - querying data

适用于所有查询过程。提供类型安全的 Tanstack 的 queryOptions 功能 封装器。第一个参数是过程的输入,第二个参数接受任何原生 Tanstack React Query 选项。

¥Available for all query procedures. Provides a type-safe wrapper around Tanstack's queryOptions function. The first argument is the input for the procedure, and the second argument accepts any native Tanstack React Query options.

ts
const queryOptions = trpc.path.to.query.queryOptions(
{
/** input */
},
{
// Any Tanstack React Query options
stateTime: 1000,
},
);
ts
const queryOptions = trpc.path.to.query.queryOptions(
{
/** input */
},
{
// Any Tanstack React Query options
stateTime: 1000,
},
);

你还可以向 queryOptions 函数提供 trpc 对象,以便向客户端提供 tRPC 请求选项。

¥You can additionally provide a trpc object to the queryOptions function to provide tRPC request options to the client.

ts
const queryOptions = trpc.path.to.query.queryOptions(
{
/** input */
},
{
trpc: {
// Provide tRPC request options to the client
context: {
// see https://trpc.nodejs.cn/docs/client/links#managing-context
},
},
},
);
ts
const queryOptions = trpc.path.to.query.queryOptions(
{
/** input */
},
{
trpc: {
// Provide tRPC request options to the client
context: {
// see https://trpc.nodejs.cn/docs/client/links#managing-context
},
},
},
);

结果可以传递给 useQueryuseSuspenseQuery 钩子或查询客户端方法,如 fetchQueryprefetchQueryprefetchInfiniteQueryinvalidateQueries 等。

¥The result can be passed to useQuery or useSuspenseQuery hooks or query client methods like fetchQuery, prefetchQuery, prefetchInfiniteQuery, invalidateQueries, etc.

infiniteQueryOptions - 查询无限数据

¥infiniteQueryOptions - querying infinite data

适用于所有接受光标输入的查询过程。提供类型安全的 Tanstack 的 infiniteQueryOptions 功能 封装器。第一个参数是过程的输入,第二个参数接受任何原生 Tanstack React Query 选项。

¥Available for all query procedures that takes a cursor input. Provides a type-safe wrapper around Tanstack's infiniteQueryOptions function. The first argument is the input for the procedure, and the second argument accepts any native Tanstack React Query options.

ts
const infiniteQueryOptions = trpc.path.to.query.infiniteQueryOptions(
{
/** input */
},
{
// Any Tanstack React Query options
getNextPageParam: (lastPage, pages) => lastPage.nextCursor,
},
);
ts
const infiniteQueryOptions = trpc.path.to.query.infiniteQueryOptions(
{
/** input */
},
{
// Any Tanstack React Query options
getNextPageParam: (lastPage, pages) => lastPage.nextCursor,
},
);

queryKey - 获取查询密钥并在查询客户端上执行操作

¥queryKey - getting the query key and performing operations on the query client

适用于所有查询过程。允许你以类型安全的方式访问查询键。

¥Available for all query procedures. Allows you to access the query key in a type-safe manner.

ts
const queryKey = trpc.path.to.query.queryKey();
ts
const queryKey = trpc.path.to.query.queryKey();

由于 Tanstack React Query 使用模糊匹配作为查询键,因此你还可以为任何子路径创建部分查询键以匹配属于路由的所有查询:

¥Since Tanstack React Query uses fuzzy matching for query keys, you can also create a partial query key for any sub-path to match all queries belonging to a router:

ts
const queryKey = trpc.router.pathKey();
ts
const queryKey = trpc.router.pathKey();

甚至是匹配所有 tRPC 查询的根路径:

¥Or even the root path to match all tRPC queries:

ts
const queryKey = trpc.pathKey();
ts
const queryKey = trpc.pathKey();

queryFilter - 创建查询过滤器

¥queryFilter - creating query filters

适用于所有查询过程。允许以类型安全的方式创建 查询过滤器

¥Available for all query procedures. Allows creating query filters in a type-safe manner.

ts
const queryFilter = trpc.path.to.query.queryFilter(
{
/** input */
},
{
// Any Tanstack React Query filter
predicate: (query) => {
query.state.data;
},
},
);
ts
const queryFilter = trpc.path.to.query.queryFilter(
{
/** input */
},
{
// Any Tanstack React Query filter
predicate: (query) => {
query.state.data;
},
},
);

与查询键一样,如果你想在整个路由上运行过滤器,则可以使用 pathFilter 来定位任何子路径。

¥Like with query keys, if you want to run a filter across a whole router you can use pathFilter to target any sub-path.

ts
const queryFilter = trpc.path.pathFilter({
// Any Tanstack React Query filter
predicate: (query) => {
query.state.data;
},
});
ts
const queryFilter = trpc.path.pathFilter({
// Any Tanstack React Query filter
predicate: (query) => {
query.state.data;
},
});

可用于创建可以传递给客户端方法(如 queryClient.invalidateQueries 等)的过滤器。

¥Useful for creating filters that can be passed to client methods like queryClient.invalidateQueries etc.

mutationOptions - 创建突变选项

¥mutationOptions - creating mutation options

适用于所有变异过程。提供类型安全的识别函数,用于构建可传递给 useMutation 的选项。

¥Available for all mutation procedures. Provides a type-safe identify function for constructing options that can be passed to useMutation.

ts
const mutationOptions = trpc.path.to.mutation.mutationOptions({
// Any Tanstack React Query options
onSuccess: (data) => {
// do something with the data
},
});
ts
const mutationOptions = trpc.path.to.mutation.mutationOptions({
// Any Tanstack React Query options
onSuccess: (data) => {
// do something with the data
},
});

mutationKey - 获取突变密钥

¥mutationKey - getting the mutation key

适用于所有变异过程。允许你以类型安全的方式获取突变密钥。

¥Available for all mutation procedures. Allows you to get the mutation key in a type-safe manner.

ts
const mutationKey = trpc.path.to.mutation.mutationKey();
ts
const mutationKey = trpc.path.to.mutation.mutationKey();

subscriptionOptions - 创建订阅选项

¥subscriptionOptions - creating subscription options

TanStack 不提供订阅钩子,因此我们继续在这里公开我们自己的抽象,它可以与 标准 tRPC 订阅设置 一起使用。适用于所有订阅过程。提供类型安全的识别函数,用于构建可传递给 useSubscription 的选项。请注意,你需要在 tRPC 客户端中配置 httpSubscriptionLinkwsLink 才能使用订阅。

¥TanStack does not provide a subscription hook, so we continue to expose our own abstraction here which works with a standard tRPC subscription setup. Available for all subscription procedures. Provides a type-safe identify function for constructing options that can be passed to useSubscription. Note that you need to have either the httpSubscriptionLink or wsLink configured in your tRPC client to use subscriptions.

tsx
function SubscriptionExample() {
const trpc = useTRPC();
const subscription = useSubscription(
trpc.path.to.subscription.subscriptionOptions(
{
/** input */
},
{
enabled: true,
onStarted: () => {
// do something when the subscription is started
},
onData: (data) => {
// you can handle the data here
},
onError: (error) => {
// you can handle the error here
},
onConnectionStateChange: (state) => {
// you can handle the connection state here
},
},
),
);
// Or you can handle the state here
subscription.data; // The lastly received data
subscription.error; // The lastly received error
/**
* The current status of the subscription.
* Will be one of: `'idle'`, `'connecting'`, `'pending'`, or `'error'`.
* * - `idle`: subscription is disabled or ended
* - `connecting`: trying to establish a connection
* - `pending`: connected to the server, receiving data
* - `error`: an error occurred and the subscription is stopped
*/
subscription.status;
// Reset the subscription (if you have an error etc)
subscription.reset();
return <>{/* ... */}</>;
}
tsx
function SubscriptionExample() {
const trpc = useTRPC();
const subscription = useSubscription(
trpc.path.to.subscription.subscriptionOptions(
{
/** input */
},
{
enabled: true,
onStarted: () => {
// do something when the subscription is started
},
onData: (data) => {
// you can handle the data here
},
onError: (error) => {
// you can handle the error here
},
onConnectionStateChange: (state) => {
// you can handle the connection state here
},
},
),
);
// Or you can handle the state here
subscription.data; // The lastly received data
subscription.error; // The lastly received error
/**
* The current status of the subscription.
* Will be one of: `'idle'`, `'connecting'`, `'pending'`, or `'error'`.
* * - `idle`: subscription is disabled or ended
* - `connecting`: trying to establish a connection
* - `pending`: connected to the server, receiving data
* - `error`: an error occurred and the subscription is stopped
*/
subscription.status;
// Reset the subscription (if you have an error etc)
subscription.reset();
return <>{/* ... */}</>;
}

推断输入和输出类型

¥Inferring Input and Output types

当你需要推断过程或路由的输入和输出类型时,根据情况有 2 个选项可用。

¥When you need to infer the input and output types for a procedure or router, there are 2 options available depending on the situation.

推断完整路由的输入和输出类型

¥Infer the input and output types of a full router

ts
import type { inferRouterInputs, inferRouterOutputs } from '@trpc/server';
import { AppRouter } from './path/to/server';
export type Inputs = inferRouterInputs<AppRouter>;
export type Outputs = inferRouterOutputs<AppRouter>;
ts
import type { inferRouterInputs, inferRouterOutputs } from '@trpc/server';
import { AppRouter } from './path/to/server';
export type Inputs = inferRouterInputs<AppRouter>;
export type Outputs = inferRouterOutputs<AppRouter>;

推断单个过程的类型

¥Infer types for a single procedure

ts
import type { inferInput, inferOutput } from '@trpc/tanstack-react-query';
function Component() {
const trpc = useTRPC();
type Input = inferInput<typeof trpc.path.to.procedure>;
type Output = inferOutput<typeof trpc.path.to.procedure>;
}
ts
import type { inferInput, inferOutput } from '@trpc/tanstack-react-query';
function Component() {
const trpc = useTRPC();
type Input = inferInput<typeof trpc.path.to.procedure>;
type Output = inferOutput<typeof trpc.path.to.procedure>;
}

访问 tRPC 客户端

¥Accessing the tRPC client

如果你使用了 使用 React Context 设置,则可以使用 useTRPCClient 钩子访问 tRPC 客户端。

¥If you used the setup with React Context, you can access the tRPC client using the useTRPCClient hook.

tsx
import { useTRPCClient } from './trpc';
function Component() {
const trpcClient = useTRPCClient();
const result = await trpcClient.path.to.procedure.query({
/** input */
});
}
tsx
import { useTRPCClient } from './trpc';
function Component() {
const trpcClient = useTRPCClient();
const result = await trpcClient.path.to.procedure.query({
/** input */
});
}

如果你 不使用 React Context 设置,你可以直接导入全局客户端实例。

¥If you setup without React Context, you can import the global client instance directly instead.

ts
import { client } from './trpc';
const result = await client.path.to.procedure.query({
/** input */
});
ts
import { client } from './trpc';
const result = await client.path.to.procedure.query({
/** input */
});