tRPC封装react-query:组件需等所有查询完成才更新的问题
问题分析与解决方案
可能的原因及对应解决办法
1. 服务器端渲染(SSR)预取导致同步渲染
如果你的项目基于SSR框架(如Next.js),且当前组件在服务器端渲染,tRPC默认会在服务端预执行所有useQuery调用,等待所有查询完成后才生成完整HTML返回给客户端。这会导致客户端拿到页面时,两个查询结果已全部就绪,自然看不到中间的“等待”状态。
解决办法:
给useQuery添加{ ssr: false }选项,强制仅在客户端发起查询:
const sample1Result = api.myRouter.sampleRequest1.useQuery(undefined, { ssr: false }) const sample2Result = api.myRouter.sampleRequest2.useQuery(undefined, { ssr: false })
2. 父组件阻止重渲染
如果MyComponent被包裹在使用React.memo、自定义shouldComponentUpdate的父组件中,可能会导致子组件的状态更新无法触发重渲染,看起来像是两个查询完成后才一起更新。
解决办法:
- 暂时移除父组件的
React.memo或渲染拦截逻辑,验证是否解决问题; - 若需保留优化,给
React.memo添加精准的依赖比较函数,确保能响应子组件的状态变化。
3. tRPC客户端配置异常
若tRPC客户端全局配置了错误的缓存策略,比如设置了过长的staleTime,或查询key出现冲突,可能导致状态更新不及时。
解决办法:
- 检查客户端初始化代码,确认未设置全局
staleTime为无限大; - 手动指定唯一查询key,避免潜在冲突:
const sample1Result = api.myRouter.sampleRequest1.useQuery(undefined, { queryKey: ['sample-request-1'] }) const sample2Result = api.myRouter.sampleRequest2.useQuery(undefined, { queryKey: ['sample-request-2'] })
验证步骤
- 打开浏览器Network面板,确认两个请求并行发起,且第一个请求在5秒后返回成功;
- 在组件内添加
console.log(sample1Result.data, sample2Result.data),判断是数据未更新还是组件未渲染:- 若数据在5秒后已更新但组件未刷新,说明重渲染被阻止;
- 若数据也未更新,需排查tRPC的查询状态同步逻辑。
内容的提问来源于stack exchange,提问作者C G
相关产品推荐
相关产品推荐

