如何最好地从反应查询缓存中获取数据?

how to best get data from react-query cache?

所以反应查询缓存是一个键值存储,但这是一种限制,不是吗?我认为最好将网络请求保持在最低限度,因为它们花费的时间比从缓存中获取数据要长几个数量级。话虽这么说,如果我有一个路由 /todos 作为所有待办事项的页面和一个子路由 /todos/FE234F32 作为一些随机待办事项的页面,那么所有待办事项的查询键将是 ["todos"] 和特定的查询键是 ["todos", "FE234F32"],然后假设我首先访问包含所有待办事项的页面,我将在缓存中获得所有待办事项的数据,但是如果我转到特定待办事项的页面将发出网络请求,因为 ["todos", "FE234F32"].

没有值

我知道我可以在 ["todos", "FE234F32"] 的查询函数中做一个 getQueryData("todos") 这样我就可以检查数据是否已经在缓存中但是那种基于条件的解决方案缓存中有更大的虚拟层次结构会使代码看起来很糟糕。一般来说,似乎大多数状态解决方案都是分层的或基于对象的。但是 react-query 的键值性质要么导致获取太多数据并选择向下或获取缓存中已经存在的数据。

我在这里可能完全偏离基地,但我会喜欢一些 insight/tips!

react-query 有很多方法可以做到这一点。如果列表查询的数据结构与详细查询的数据结构确实相同,则可以在获取列表后将其下拉查询,这将预填充详细信息缓存:

useQuery(
  'posts',
  fn,
  {
    onSuccess: data => data.map(post =>
      queryClient.setQueryData(['posts', id], post)
  }
)

结合正确的 staleTime 设置,您可以避免额外的提取。

一旦通过 initialData:

安装详细查询,您也可以执行相反的操作并提取数据
useQuery(
  ['posts', id],
  fn,
  {
    initialData: () =>
      queryClient.getQueryData(['posts']?.find(post => post.id === id)
  }
)

最后,如果你的数据真的总是一样的,你可以考虑使用select函数从列表查询中抓取数据,而不是进行额外的抓取。如果您需要一个细节的数据并且缓存中还没有数据,那么它的缺点是总是重新获取整个列表:

const usePosts = (select) => useQuery(['posts'], fetchPosts)
const usePost = (id) => usePosts(data => data.find(post => post.id === id))