使用trpc.useContext()失效数据引发无限循环问题求助
核心问题根源
无限循环的本质是invalidate触发查询重跑,重跑后又触发了invalidate操作,形成闭环,和是否定位具体邀请没有必然关联,但精准操作缓存能从根源上避免这类问题。
排查与解决步骤
检查查询依赖项
看看你用useQuery调用getInviteList时,有没有把删除相关的状态(比如待删除ID、按钮loading状态)当成了查询的依赖数组项。如果这些状态在invalidate后没有被重置,会反复触发查询,进而再次触发invalidate,形成循环。
比如如果你的查询是这种写法:useQuery([inviteRoute.getInviteList, currentDeleteId], () => ...)那
currentDeleteId的变化会反复触发查询,必须确保删除完成后重置currentDeleteId,或者把它移出查询依赖。检查突变的onSuccess逻辑
你是不是在deleteInvite的useMutation的onSuccess里直接调用了invalidate()?如果getInviteList查询结果更新后,组件里又有监听结果变化并触发删除/invalidate的逻辑,就会形成闭环。
比如组件里写了useEffect监听getInviteList的返回值,一旦更新就执行了某些和删除相关的操作,那必然会循环。用精准缓存更新替代全量invalidate
与其调用inviteRoute.getInviteList.invalidate()触发全量查询重跑,不如直接手动更新缓存,移除被删除的邀请项,这种方式不会触发查询重跑,从根源上避免循环:const queryClient = useQueryClient(); const deleteInviteMutation = useMutation(deleteInvite, { onSuccess: (_, deletedId) => { // 直接更新缓存,移除对应项 queryClient.setQueryData([inviteRoute.getInviteList], (oldList) => { return oldList?.filter(invite => invite.id !== deletedId) ?? oldList; }); }, });排查组件渲染逻辑
检查删除按钮的点击事件是否被重复绑定,或者useMutation是否被放在了条件渲染块里,导致组件重新渲染时重复创建突变实例,触发意外的invalidate操作。
内容的提问来源于stack exchange,提问作者Mossy82

