Search code examples
reactjscachingapolloapollo-clientreact-query

How React Query or Apollo Client ensures updated data?


Both React Query and Apollo Client cache the API response and the second time, a new request is not sent but data is returned from the cache. And, if the data changes at backend, the data is also updated in the cache.

  1. But how does React Query or Apollo client knows that when to send a new API request or when to send data from cache? Are there any background network requests going on?

  2. If so then why don't we see any of the API request in the network tab when data is returned from the cache?

  3. If React Query is sending API requests in background to check if data has updated, isn't it the waste of resources because we are sending unnecessary API calls in the background and may be the data never changes but we are continuously sending API requests?

I tried looking for this but I couldn't find the satisfactory answer. Everywhere it says the data is data is cached and cache is updated but how does this happens? Can anyone please explain the process?


Solution

  • Trying to answer from react-queries perspective:

    1. But how does React Query or Apollo client knows that when to send a new API request or when to send data from cache? Are there any background network requests going on?

    React Query embraces the stale-while-revalidate caching mechanism, which means when there is data in the cache, you will get it instantly (even though it might not be up-to-date anymore), and then there might be background updates at strategic points in time. Those points in time include when you refocus the browser window or when a new component mounts that uses a query. RQ does not re-fetch on every re-render.

    1. If so then why don't we see any of the API request in the network tab when data is returned from the cache?

    only stale queries are being refetched - this can be customized by setting staleTime. The default value is 0 (zero) - so every query is considered stale per default, so that react-query can update it at those strategic points in time. So if a query is not stale, or you're not hitting one of those strategic points, you will just get data from the cache without a background refetch.

    1. If React Query is sending API requests in background to check if data has updated, isn't it the waste of resources because we are sending unnecessary API calls in the background and may be the data never changes but we are continuously sending API requests?

    Potentially yes, but this depends on your resource. React Query, per default, tries to optimize for data accuracy rather than minimizing the amount of network requests. This can be customized by setting staleTime. If you only want to fetch once and then never update again, try setting a higher staleTime.

    I'm trying to cover this in my article React Query as a State Manager:

    The answer depends totally on our problem domain. If we fetch a Twitter post with all its likes and comments, it is likely outdated (stale) pretty fast. If we fetch exchange rates that update on a daily basis, well, our data is going to be quite accurate for some time even without refetching.

    Another way to optimize how often your backend gets hit by requests is to use http caching. You can see this in action in the simple example from the docs, where we query against the github api. It answers with the following cache-control header:

    cache-control: public, max-age=60, s-maxage=60

    which means that even though react-query attempts a refetch on every focus of the browser tab, the network requests will not hit the github api for the next 60 seconds. You can still see the request in the network tab of your browser devtools, but the response will come from the "disk cache" instead.