Understanding 'cache-and-network' fetchPolicy?

I’d like to improve my understanding of the ‘cache-and-network’ fetchPolicy.

From the docs:

Apollo Client executes the full query against both the cache and your GraphQL server. The query automatically updates if the result of the server-side query modifies cached fields.

Okay, I think I get that. Apollo Client will query the server and the cache and merge any new results from the server into the cache.

Provides a fast response while also helping to keep cached data consistent with server data.

This is the part about which I need to improve my understanding. If it first displays the cached result, and then gets a different result back from the server, do I need to detect that and do something to refresh my component to show the updated results?

Nope, the component will be rerendered with the new data automatically!

2 Likes

So cool! How is that possible – can a hook cause a re-render without changing state? Or possibly, is it my responsibility to take the data returned by Apollo and put it in a local state variable, causing a re-render that way?

Individual fields in the Apollo Client cache sort of are local state variables that are automatically associated with particular queries. Whenever you execute a query with Apollo Client, Apollo Client associates that query with the cached fields that it queried for.

Then, whenever a cached field is updated, Apollo Client automatically triggers a refresh of every “active” query that depends on that field. (A query is active if the rendered component that executed it is still around.) This occurs unless you very specifically prevent it with a cache modification.

So, you don’t need to do anything special! When your server’s actual response comes back, the cached fields are updated, and your active queries treat that as a state change that merits a refresh :+1:

I just tested it, and it correctly brought in the changes I’d manually made to the db. :slight_smile:

Here’s how I tested it:

  • Displayed the page
  • Manually edited the db in a db client
  • Clicked to another page
  • Clicked back to the first page
  • The new data was there!

When data comes back from the query, I put it in a useRef like this:

if (data) {
    console.log('cp #1');
    messageFolders.current = data.messageFolders;
}

Now, console.log('cp #1') only ran one time. I was expecting Apollo to hit the cache and get data that would go in my useRef, then hit the server and put data in the useRef again. So, I was expecting to see console.log('cp #1') called two times - once for the read from the cache, and once for the read from the server. But, it was only called one time.

Is that what I should expect to be seeing?