React Native集成tRPC始终显示加载状态问题求助
tRPC + Fastify 在React Native中持续加载问题的排查与修复
先修复代码中的致命错误
你提供的代码里重复定义了两次TRPCProvider,这会导致组件被覆盖,属于明显的语法错误,先删掉重复的那段定义,只保留一个即可。
核心问题排查与解决步骤
1. 调整Provider嵌套顺序
当前代码里tRPC.Provider包裹了QueryClientProvider,这是错误的——tRPC依赖react-query的上下文,必须让tRPC.Provider处于QueryClientProvider的作用域内。正确的嵌套顺序:
return ( <QueryClientProvider client={queryClient}> <trpc.Provider client={trpcClient} queryClient={queryClient}> {children} </trpc.Provider> </QueryClientProvider> );
2. 验证localhost地址的正确性
React Native不同平台的localhost映射规则不一样:
- Android模拟器不能直接用
localhost,需要用10.0.2.2(模拟器映射本地电脑的专用IP) - iOS模拟器可以直接用
localhost,但debuggerHost可能拿到的是电脑的局域网IP,建议手动打印getBaseUrl()的结果确认地址是否正确
修改后的getBaseUrl可以兼容多平台:
import { Platform } from 'react-native'; const getBaseUrl = () => { if (Platform.OS === 'android') { return 'http://10.0.2.2:3000/trpc'; } const localhost = Constants.manifest?.debuggerHost?.split(':')[0]; if (!localhost) { throw new Error('无法获取localhost,请手动配置'); } return `http://${localhost}:3000/trpc`; };
3. 添加请求错误日志定位问题
在tRPC的httpBatchLink里加入错误日志,直接查看请求失败的原因(网络不通、服务端报错等):
httpBatchLink({ url: getBaseUrl(), onError(opts) { console.error('tRPC请求错误详情:', opts.error); console.error('对应请求信息:', opts.request); }, })
4. 检查Fastify的跨域配置
虽然Next.js里正常,但React Native属于独立客户端,需要确保Fastify开启了CORS:
// Fastify服务端代码 import cors from '@fastify/cors'; await fastify.register(cors, { origin: true, // 开发环境允许所有来源,生产环境替换为具体域名 credentials: true, });
5. 调整react-query的默认配置
如果请求发送成功但一直显示加载,可能是react-query的缓存或重试机制导致,开发环境可以关闭重试并开启日志:
const [queryClient] = useState(() => new QueryClient({ defaultOptions: { queries: { retry: false, refetchOnWindowFocus: false, }, }, logger: { log: console.log, error: console.error, }, }));
修复后的完整代码示例
import { useState } from 'react'; import { Platform } from 'react-native'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { trpc } from '../path/to/your/trpc/client'; // 替换为你的tRPC客户端路径 import Constants from 'expo-constants'; const getBaseUrl = () => { if (Platform.OS === 'android') { return 'http://10.0.2.2:3000/trpc'; } const localhost = Constants.manifest?.debuggerHost?.split(':')[0]; if (!localhost) { throw new Error('无法获取localhost,请手动配置'); } return `http://${localhost}:3000/trpc`; }; export const TRPCProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { console.log('当前tRPC服务地址:', getBaseUrl()); const [queryClient] = useState(() => new QueryClient({ defaultOptions: { queries: { retry: false, }, }, })); const [trpcClient] = useState(() => trpc.createClient({ links: [ httpBatchLink({ url: getBaseUrl(), onError(opts) { console.error('tRPC请求失败:', opts.error); }, }), ], }), ); return ( <QueryClientProvider client={queryClient}> <trpc.Provider client={trpcClient} queryClient={queryClient}> {children} </trpc.Provider> </QueryClientProvider> ); };
内容的提问来源于stack exchange,提问作者bonjofy
相关产品推荐
相关产品推荐

