I have an RTK Query endpoint that gets a list of data, and I have other components that uses the same data returned from the query. One component uses a subset of the list with some common attribute, and another component shows details of an item from the list — getById. These components are not rendered in order; any of the components can render first.
How can I utilized the same results in all of these components, and only fetch once or when the results has been invalidated?
I tried using selectFromResults, but this only assumes that the data has been fetched from a parent component (doesn’t really trigger fetching — unless I’m wrong). If I’m not wrong, the RTK team should probably consider a patch for this issue?
I know I can call the query in all the components and it’ll just get the cached data. I’m just wondering if there’s a better solution.
I can also copy the data to the redux store and manage it myself, and off course I would be missing out on the benefits of RTKQ, plus this will also create duplicate.
2
Answers
You’re right that the most efficient way is to use the query wherever you need it. If you add another hook that hits the same endpoint with the same parameters, both will use the same cache entry. That’s the most efficient way to do it.
selectFromResults
should trigger a query if it hasn’t already run, or you can usecreateSelector
to create a memoized selector and just use it inline on your returned data.You can utilize upsertQueryData and manage the cache entries by yourself if possible depending on which data was fetched first – a list of items, or single item by id.
Basing on your question, I assume you have two endpoints returning one or n of the same items
getPostById
– which returns single post item of type:interface Post {}
getPostsList
– which returns a list of items with the same shape asgetPostById
of type:type PostsList = Post[]
Then, if
getPostsList
query returns data, we can easily useupsertQueryData
to manually create cache entries for eachgetPostById
to prevent refetching it on enter the<Post/>
component:Now, if you first load a list component
<PostsList/>
requesting forgetPostsList
and then you enter a<Post/>
component requesting forgetPostById
(where you havepostApi.endpoints.getPostById.useQuery({ id })
), no request is fired, because you already have all data in the cache (from pessimistic update based ongetPostsList
response).It’s the only scenario when you can prefill the cache data. If first you request for
getPostById
and later for a list, there is no space for optimization because frontend has no clue that previously requested by id posts will be in the list or not.