You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Expo + tRPC报错:无法获取应用上下文,是否未用withTRPC HoC?

问题描述

我用tRPC编写了服务端代码,客户端基于expo-template-blank-typescript实现,但运行时弹出错误提示:"Did you forget to wrap your App inside withTRPC HoC?"。我已经在App的渲染树中配置了trpc.Provider和QueryClientProvider,但还是找不到问题所在,求排查思路。

服务端代码(server.ts)

// server.ts
import { initTRPC } from "@trpc/server";
import { z } from "zod";

const t = initTRPC.create();

export const appRouter = t.router({
    greeting: t.procedure
        .input(
            z.object({
                name: z.string().optional()
            }))
        .query(({ input }) => {
            return {
                message: `hello ${input.name ?? "world"}`
            };
        }),
});

export type AppRouter = typeof appRouter;

客户端代码(App.tsx)

// App.tsx
import { StyleSheet, Text, View } from 'react-native';
import { StatusBar } from 'expo-status-bar';

import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { createTRPCReact, httpBatchLink } from '@trpc/react-query';
import type { AppRouter } from '../backend';

const queryClient = new QueryClient();

const trpc = createTRPCReact<AppRouter>();

const trpcClient = trpc.createClient({
  links: [
    httpBatchLink({
      url: "http://localhost:9696"
    })
  ]
})

export default function App() {
  return (
    <trpc.Provider client={trpcClient} queryClient={queryClient}>
      <QueryClientProvider client={queryClient}>
        <View style={styles.container}>
          <Text>Open up App.tsx to start working on your app!</Text>
          <Text>{trpc.greeting.useQuery({ name: "expo client" }).data?.message}</Text>
          <StatusBar style="auto" />
        </View>
      </QueryClientProvider>
    </trpc.Provider>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});
排查思路
  • 调整Provider层级顺序:trpc.Provider必须放在QueryClientProvider内部,因为tRPC的Provider依赖React Query的上下文。当前代码把trpc.Provider包在外面,会导致tRPC无法获取到React Query的实例,正确写法如下:

    <QueryClientProvider client={queryClient}>
      <trpc.Provider client={trpcClient} queryClient={queryClient}>
        {/* 应用内容 */}
      </trpc.Provider>
    </QueryClientProvider>
    
  • 修正Hook调用位置:你在JSX表达式里直接调用trpc.greeting.useQuery(),违反了React Hooks的调用规则——Hooks必须在组件顶层作用域调用,不能嵌套在JSX里。要把Hook调用移到组件最外层:

    export default function App() {
      // 移到组件顶层
      const greetingQuery = trpc.greeting.useQuery({ name: "expo client" });
      
      return (
        <QueryClientProvider client={queryClient}>
          <trpc.Provider client={trpcClient} queryClient={queryClient}>
            <View style={styles.container}>
              <Text>Open up App.tsx to start working on your app!</Text>
              <Text>{greetingQuery.data?.message}</Text>
              <StatusBar style="auto" />
            </View>
          </trpc.Provider>
        </QueryClientProvider>
      );
    }
    
  • 检查版本兼容性:确认@trpc/react-query和@tanstack/react-query的版本是否匹配,不同版本的tRPC对Provider的配置要求可能有差异,建议核对对应版本的官方文档。

  • 排查上下文穿透问题:如果App组件外层还有其他自定义Provider或路由组件,可能会阻断上下文传递,确保trpc.Provider和QueryClientProvider包裹了所有使用tRPC Hooks的组件。

内容的提问来源于stack exchange,提问作者Fatih Mar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 02:27:39