How to re-fetch single items of a collection in react-query

Viewed 1337

Let's say i have a query to fetch a collection of movies:

useQuery(['movies'], getMovies)

Now, if I want to re-fetch only one movie instead of all I can write something like this:

useQuery(['movies', movieId], () => getMovie(movieId))

Problem is that I use a different query key and that it will duplicate the data. I'll have the movie in my cache twice.

So, what's the react-query way of updating a single item of a fetched collection? All components that use useQuery(['movies']) should be updated automatically when the single item was fetched.

1 Answers

I think there are two ways:

  1. like you described with a new key. yes, the data will be "twice" in the cache, but oftentimes, the "list" data has a different structure than the "detail" data. movies-list might just have id and name, while the details have a description etc. as well. If you do that, make sure to give them both the same prefix ('movies'), so that you can utilize the fuzzy matching when invalidating: queryClient.invalidateQueries(['movies']) will then invalidate the list and all details, which is nice.

  2. you can use the select option to build a detail query on:

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

with that, you can do useMovie(5) and thus will only subscribe to the movie with id 5. This is really nice and also render optimized - if the movie with id 4 updates, the component that subscribes to movie with id 5 will not re-render.

the "drawback" is of course that for the data / network perspective, there is only one query - the list query, so everytime you do background refetches, the whole list will be queried from the backend. But it's still a nice approach to avoid data duplication in the cache, and it makes optimistic updates easier as well, because you only have to write to update one cache entry.

Related