如何在反应查询中重新获取集合中的单个项目

Alp*_*Alp 4 normalization reactjs react-query

假设我有一个查询来获取电影集合:

useQuery(['movies'], getMovies)
Run Code Online (Sandbox Code Playgroud)

现在,如果我只想重新获取一部电影而不是所有电影,我可以编写如下内容:

useQuery(['movies', movieId], () => getMovie(movieId))
Run Code Online (Sandbox Code Playgroud)

问题是我使用不同的查询键并且它会重复数据。我会将这部电影放入缓存中两次。

那么,更新获取的集合中的单个项目的反应查询方式是什么?useQuery(['movies'])当获取单个项目时,所有使用的组件都应该自动更新。

TkD*_*odo 6

我认为有两种方法:

  1. 就像你用新钥匙描述的那样。是的,数据将在缓存中“两次”,但通常,“列表”数据与“详细”数据具有不同的结构。电影列表可能只有 ID 和名称,而详细信息也有描述等。如果这样做,请确保为它们提供相同的前缀 ( 'movies'),以便您可以在失效时利用模糊匹配:queryClient.invalidateQueries(['movies'])然后将使列表和所有详细信息失效,这很好。

  2. 您可以使用 select 选项构建详细查询:

const useMovies = (select) => useQuery(['movies'], getMovies, { select })
const useMovie = (id) => useMovies(movies => movies.find(movie => movie.id === id))
Run Code Online (Sandbox Code Playgroud)

这样,您就可以这样做useMovie(5),因此只会订阅 id 5 的电影。这非常好,并且还进行了渲染优化 - 如果 id 4 的电影更新,订阅 id 5 的电影的组件将不会重新渲染。

当然,“缺点”是,从数据/网络角度来看,只有一个查询 - 列表查询,因此每次进行后台重新获取时,都会从后端查询整个列表。但这仍然是避免缓存中数据重复的一种好方法,并且它也使乐观更新变得更容易,因为您只需写入即可更新一个缓存条目。