ReactQuery - useInfiniteQuery 重新获取问题

Sab*_*bin 11 reactjs react-query

我已经在使用React Query库的项目上实现了无限滚动。

到目前为止,一切都很好。useInfiniteScroll使用钩子一切都按预期工作

我遇到的一个问题是这个库的缓存机制。如果我查询资源,例如: GET /posts/,将触发 GET /posts/?page=0,向下滚动一点,获取下一个结果, GET/posts/?page=1完全没问题。如果我将搜索参数添加到页面将执行 GET /posts/?filter=someValue&page=0。一切都很好...但是当我filter从搜索中删除它时,它会自动执行 GET /posts/?page=0& GET/posts/?page=1

remove()解决方案是使用查询本身的方法从缓存中删除查询。但这意味着我必须为每个查询手动执行此操作。

我希望获得一个涵盖所有情况的更好的解决方案。我有一个 queryWrapper 我想在其中处理这个问题。

我尝试使用 queryClient 实例invalidateQueriesresetQueries但似乎没有人能够将其从缓存中删除......

在下面的示例中,我保留了ref参数,如果它们发生更改,我可以触发查询以通过useLayoutEffect钩子重置。这部分按预期工作

无效查询尝试

queryClient.invalidateQueries(
    [queryKey, JSON.stringify(paramsRef.current)],
    {
      exact: true,
      refetchActive: false,
      refetchInactive: false
    },
    { cancelRefetch: true }
);
Run Code Online (Sandbox Code Playgroud)

重置查询尝试

queryClient
    .resetQueries([queryKey, JSON.stringify(paramsRef.current)], {
      refetchPage: (page, index) => index === 0
    })
Run Code Online (Sandbox Code Playgroud)

我什至尝试了queryClient.clear()应该从缓存中删除所有现有查询的方法,但页码仍然以某种方式保留在缓存中...我使用useQueryClient钩子访问 queryClient。如果我检查它,我可以看到里面的查询。

有人可以帮我解决这个缓存问题吗?谢谢!

TkD*_*odo 11

但是当我从搜索中删除过滤器时,它会自动执行 GET /posts/?page=0 和 GET /posts/?page=1

这是默认的react-query重新获取行为:无限查询只有一个缓存条目,具有多个页面。当重新获取发生时,所有当前可见的页面都将被重新获取。此处记录了这一点。

这对于一致性是必要的,因为例如,如果从第 1 页中删除了一个条目,并且我们不会重新获取第 2 页,则第 2 页(旧)上的第一个条目将等于第 1 页(新)的最后一个条目。

现在真正的问题是,当过滤器发生变化时,您是否想要重新获取?如果没有,那么设置 astaleTime将是最好的解决方案。如果您确实想要重新获取,重新获取所有页面是最安全的选择。queryClient.setQueryData否则,您可以尝试在查询卸载时删除除第一个页面之外的所有页面。React-query 不会自动执行此操作,因为为什么我们要删除用户已向下滚动到已查看的数据。

另请注意,对于命令式重新获取,例如invalidateQueries,您可以选择传递一个refetchPage函数,您可以在其中为每个页面返回一个布尔值以指示是否应该重新获取。如果您只更新一项并且只想重新获取该项所在的页面,这会很有帮助。此处记录了这一点。

  • 您的缓存中有两个页面,因此它们都会被重新获取。如果您可以忍受硬加载状态,请设置“cacheTime:0”。一旦密钥发生变化,这将删除所有内容,并且当您返回时您将重新开始。除此之外,您必须在 useEffect 中使用 queryClient.setQueryData 手动对页面和 pageParams 进行切片,以便在键更改时仅包含一个元素 (6认同)
  • 谢谢@TkDodo!它实际上解决了我的问题。我发现这个答案非常有用。另外,给tw acc写了一些消息 (2认同)