T3 Stack中tRPC跨路由无效化非活跃查询的方案问询
T3 Stack + tRPC跨路由非活跃查询无效化解决方案
核心问题出在:离开/profile路由后,对应的查询会进入非活跃状态,默认情况下tRPC的invalidate()只会触发活跃查询重新获取,非活跃查询只会被标记为失效,但你设置了refetchOnMount: false,回到页面时不会主动拉取新数据,所以看不到更新。
下面是不用修改refetchOnMount: true或cacheTime: 0的解决方案:
方案1:精准定位查询键调用invalidate(推荐)
给invalidate()传入查询的具体参数,精准匹配要失效的缓存条目,哪怕查询处于非活跃状态也会被标记为失效。修改/student-profile里的onSuccess逻辑:
const acceptStudent = api.tasks.acceptStudent.useMutation({ async onSuccess() { try { // 传入查询参数,精准命中目标缓存 await utils.tasks.getInterestedTasksByAuthorId.invalidate({ authorId: user.id }); } catch (e) { console.error(e); } }, });
然后把/profile里的refetchOnMount改成'if-stale'——这个配置刚好符合你的需求:只有当数据被标记为失效时,才会在挂载时重新请求,平时访问直接用缓存:
// /profile路由的useQuery配置调整 const {data: tasks, isFetching} = api.tasks.getInterestedTasksByAuthorId.useQuery({ authorId: user.id }, { refetchOnMount: 'if-stale', // 仅数据失效时重新请求 refetchOnWindowFocus: false, });
方案2:主动更新缓存
如果想直接把最新数据写入缓存,不需要等回到页面再请求,可以用fetchQuery主动拉取并更新缓存:
const acceptStudent = api.tasks.acceptStudent.useMutation({ async onSuccess() { try { // 主动获取最新数据,直接覆盖缓存 await api.tasks.getInterestedTasksByAuthorId.fetchQuery({ authorId: user.id }); } catch (e) { console.error(e); } }, });
这样用户下次进入/profile时,直接读取更新后的缓存,完全不用额外请求。
原理说明
- 不带参数的
invalidate()会匹配所有同名查询,但非活跃查询只会被标记失效,不会立即更新。而你之前设置的refetchOnMount: false会阻止页面挂载时重新拉取失效数据,所以看不到变化。 - 带参数的
invalidate()能精准定位缓存条目,再配合refetchOnMount: 'if-stale',既保证了只有必要时才发请求,又能在数据失效时自动更新,完美平衡流量和体验。
内容的提问来源于stack exchange,提问作者Richard Biroš
相关产品推荐
相关产品推荐

