4

I've read the documentation, and I'm still confused about the difference between the fetch policy 'store-and-network' and 'network-only'.

"store-and-network": will reuse locally cached data and will always send a network request, regardless of whether any data was missing from the local cache or not.

"network-only": will not reuse locally cached data, and will always send a network request to fetch the query, ignoring any data that might be locally cached in Relay.

I just can't figure out what the point of 'store-and-network' is. It claims that it "will reuse locally cached data"... but it ALWAYS fetches from the network, so exactly WHAT could it possibly reuse?

In my app, I've experimented with both, and I find zero difference in behaviour. Can somebody expand on this, and perhaps demonstrate a scenario where 'store-and-network' and 'network-only' would actually return different results from a query?

Community
  • 1
  • 1
Adam Wall
  • 163
  • 8

2 Answers2

4

Through lots of experimentation, I found the answer:

'network-only' fetches the data, and does not update any values in the relay store. It will not cause other fragments to be updated.

'store-and-network' fetches the data, and then updates the store with these values. This will cause any dependent fragments to be updated, which will then cause their components to be rendered.

Adam Wall
  • 163
  • 8
2

The Relay fetch policies exist so that you can control what happens when you have stale or missing data.

The docs expand on this concept here: https://relay.dev/docs/en/a-guided-tour-of-relay#presence-of-data

However, to summarize:

  1. Missing Data: Relay garbage collects data in the store when it detects that a particular piece of data is no longer being rendered anywhere. This is handled in a variety of ways, but is usually correlated with the mounting/unmounting of components that maintain(ed) a reference to a particular fragment or query. Once Relay detects that there is no active reference to some data in the store, it schedules that data for garbage collection.

  2. Stale Data: Data can still be stale but not scheduled for garbage collection. This is the case where data is not "missing" (as it is in #1) but merely needs to be refreshed -- likely, after a mutation. There still is a reference to data in the store through a mounted component.

With this distinction, the "network-only" fetch-policy will literally ignore the cache. It will not check whether the data the component needs to render will be available; rather, it will always instigate a network request and is agnostic to the presence (or lack thereof) or staleness (or lack thereof) of data in your store, as if the store does not exist.

On the other hand, the "store-and-network" fetch-policy is sensitive to the presence (or lack thereof) or staleness (or lack thereof) of data in your store.

It will investigate whether the data needed to render a particular component exists in the store:

(a) if it does, it will render and attempt to begin rendering the children tree of components, which will go through a similar process of checking whether data is missing;

(b) if at any point in rendering the tree Relay encounters a component with data requirements that do not exist in the store, the component can't render, so a network request will always be executed.

So, "store-and-network" allows you to tightly control how the tree of components with different data requirements will render. A network request will always be made -- the fetch policy simply dictates how Relay should handle rendering / suspending the render of parts of your component subtree given the current state of your store.

In the case of (b), a good example would be a situation where you declared a fragment defining the data requirements of a component that previously unmounted, but that was shared by a component elsewhere in your app. Missing data = executing network request + suspension of rendering in the world of Relay.

In other words, the fetch policy really is about how your app renders, vs. how your app fetches.

JosephHall
  • 631
  • 6
  • 8