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
相关产品推荐
相关产品推荐

