假设我有一个查询来获取电影集合:
useQuery(['movies'], getMovies)
现在,如果我只想重新获取一部电影而不是所有电影,我可以这样写:
useQuery(['movies', movieId], () => getMovie(movieId))
问题是我使用了不同的查询键并且它会复制数据。我会在我的缓存中两次保存这部电影。
那么,更新获取集合的单个项目的反应查询方式是什么?获取单个项目时,所有使用 useQuery(['movies'])
的组件都应自动更新。
答案 0 :(得分:1)
我认为有两种方式:
就像你用新密钥描述的那样。是的,数据将在缓存中“两次”,但通常,“列表”数据与“详细信息”数据具有不同的结构。电影列表可能只有 id 和名称,而详细信息也有描述等。如果这样做,请确保为它们提供相同的前缀 ('movies'
),以便在无效时使用模糊匹配:queryClient.invalidateQueries(['movies'])
将使列表和所有详细信息无效,这很好.
您可以使用选择选项来构建详细查询:
const useMovies = (select) => useQuery(['movies'], getMovies, { select })
const useMovie = (id) => useMovies(movies => movies.find(movie => movie.id === id))
有了它,您可以执行 useMovie(5)
并且因此只会订阅 id 为 5 的电影。这真的很好,而且渲染优化 - 如果 id 4 的电影更新,订阅电影的组件id 5 不会重新渲染。
“缺点”当然是对于数据/网络的角度来说,只有一个查询——列表查询,所以每次后台refetch都会从后端查询整个列表。但这仍然是一种避免缓存中数据重复的好方法,并且它也使乐观更新更容易,因为您只需写入更新一个缓存条目。