} = useGetNotesQuery("notesList", {
// options available via setupListeners(store.dispatch) in store.js
// want it to update more often so only 15 seconds
pollingInterval: 15000,
refetchOnFocus: true,
refetchOnMountOrArgChange: true,
});
I’m trying to understand what passing in "notesList"
does as the query arg via https://redux-toolkit.js.org/rtk-query/usage/queries. The docs say it generates the callback url, but why do I need this? My getNotes
endpoint already goes to "/notes"
in my builder function/endpoints.
I notice in my redux dev tools, after subscription is fulfilled, it’s stored as querycachekey (getNotes(/notesList/). What does this do? If this is a cache key so that other instances of useGetNotesQuery
can share the same key and check the cache first, then what is the point of providing and invaliding tags inside notesApiSlice
(where getNotes
provides tags) and mutations obviously invalidate tags? Why do I need cache keys like "notesList"
if I already have the provided and invalidated tags inside my endpoints?
2
Answers
Your endpoint could use this argument for something useful.
Imagine something like
with and endpoint that has a query function like
Not every endpoint will only have a static url. If you have an endpoint like that, you can just pass
undefined
in – but most of them will take some kind of argument.@phry’s answer explains well enough what purpose the
queryArg
serves in terms of making queries, so I won’t double down on that part. It seems your question is more about what RTK does with the query argument in relation to generating cache keys and caching results.Cache keys and query tags serve two separate purposes. I’ll first quickly cover what the tags do so it’s clear they are different than cache keys.
Tags
The "provides tags" and "invalidates tags" are only used between queries and mutations that reference the same tags. If you’ve queried some specific data and provided a specific tag, and then later make a mutation that invalidates that specific tag, then any active query hooks that provide that tag "auto-magically" immediately re-query their endpoint to fetch the latest mutated data.
Think of tags more of a "signal", that is to say if a mutation marks a tag as invalid, or "dirty", that a query for that tag should run again and validate/revalidate, or "clean", the tag.
For more information, or a deeper dive, see Automated Re-fetching.
Cache Keys
What the cache keys allow you to do is save making unnecessary network requests for data that likely hasn’t updated in the backend. Let’s pretend you have an endpoint that fetches stats for sports teams, the hook is
useGetTeamStats
.The UI makes a query for the current selected team, the Tigers, id is
"2139hsdfkj30iy"
.The API request is made, a response is returned, and now a cache entry is made for the query arg
"2139hsdfkj30iy"
. Seconds later the user selects a different team, the Bears, id is"0934tjner9lknw"
.Again, the API request is made, a response is returned, and another cache entry is made for the query arg
"0934tjner9lknw"
.You’ve now two cached results in redux. Here’s where some magic happens. If the user then goes back and selects the Tigers, the hook again makes the query request.
What is different this time though is that there’s a cache hit for the key
"2139hsdfkj30iy"
! Instead of making the network request to the backend, the hook simply returns the cached response data. So long as the data is cached, no network requests will be made. Active query subscribers keep the caches alive, and there’s akeepUnusedDataFor
endpoint configuration property that keeps the cache around for X seconds after subscriptions end. If another component mounts and makes the same query prior to thekeepUnusedDataFor
expiration, the cache data is returned. The defaultkeepUnusedDataFor
is 60 seconds.You can read more about the Cache Behavior.
Conclusion
Tags are used to help automate refetching of data, the cache is used to save unnecessary network traffic.