使用TanStack React Query useInfiniteQuery时客户端数据未更新求助
React Query + tRPC useInfiniteQuery 旧数据不更新问题排查方案
1. 显式确认 staleTime 配置生效
你提到设置了 staleTime: 0,但当前代码中 useInfiniteQuery 的配置项里并未显式声明。虽然 React Query 默认 staleTime 为 0,但结合持久化缓存场景,建议显式配置确保生效,同时强制挂载时重新查询:
export const useMyNotifications = () => api.user.getNotifications.useInfiniteQuery( { limit: 20 }, { getNextPageParam: lastPage => lastPage.nextCursor, staleTime: 0, // 显式设置,避免隐式规则干扰 refetchOnMount: true, }, );
2. 修复 tRPC 接口的返回数据结构
你的 tRPC 查询逻辑中查询了 limit + 1 条数据,但未处理并返回 nextCursor,这会导致 getNextPageParam 无法获取有效值,同时 React Query 无法正确识别新数据结构,进而无法更新缓存。修改 tRPC 过程代码:
getNotifications: protectedProcedure .input( z.object({ cursor: z.string().nullish(), limit: z.number().min(1).max(20).default(20), }), ) .query(async ({ ctx, input }) => { const { cursor, limit } = input; const notifications = await ctx.db.notification.findMany({ take: limit + 1, where: { userId: ctx.user?.uid as string }, orderBy: [{ createdAt: 'desc' }, { id: 'desc' }], cursor: cursor ? { id: cursor } : undefined, include: { /* 你的关联查询内容 */ } }); // 生成下一页游标 const nextCursor = notifications.length > limit ? notifications[limit].id : null; // 返回结构化数据,确保与前端查询逻辑匹配 return { notifications: notifications.slice(0, limit), nextCursor, }; })
3. 排查持久化缓存干扰
你使用了 AsyncStoragePersister 做缓存持久化,页面加载时 React Query 会优先从本地存储恢复旧缓存,即使 staleTime: 0,也会先显示旧数据再后台请求新数据。可以通过以下方式验证:
- 临时注释
PersistQueryClientProvider代码,测试是否能正常显示新数据 - 检查
removeOldestQuery重试逻辑是否阻止了新数据替换旧缓存 - 增加全局配置确保缓存更新触发:
new QueryClient({ defaultOptions: { queries: { cacheTime: 1000 * 60 * 60 * 24, staleTime: 0, refetchOnReconnect: true, refetchOnWindowFocus: true, }, }, })
4. 强制初始查询刷新
如果上述方案无效,可以强制组件挂载时刷新查询,或禁用初始缓存数据:
export const useMyNotifications = () => { const query = api.user.getNotifications.useInfiniteQuery( { limit: 20 }, { getNextPageParam: lastPage => lastPage.nextCursor, staleTime: 0, initialData: undefined, // 禁止从缓存读取初始数据 }, ); // 组件挂载时手动触发刷新 useEffect(() => { query.refetch(); }, []); return query; };
内容的提问来源于stack exchange,提问作者Pakenfit
相关产品推荐
相关产品推荐

