Search code examples
javascriptreactjsreduxredux-toolkitrtk-query

what does this queryArg do in redux toolkit query for its hooks?


} = 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?


Solution

  • @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.

    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?

    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".

    useGetTeamStats("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".

    useGetTeamStats("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.

    useGetTeamStats("2139hsdfkj30iy")
    

    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 a keepUnusedDataFor 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 the keepUnusedDataFor expiration, the cache data is returned. The default keepUnusedDataFor is 60 seconds.

    You can read more about the Cache Behavior.

    TL;DR

    Tags are used to help automate refetching of data, the cache is used to save unnecessary network traffic.