Open awinograd opened 4 months ago
Hmm, this is a complicated mental model - please stay with me :)
When the fetch happens in SSR, two things happen in the browser:
The reason 1. happens is so that other calls to useSuspenseQuery
or useQuery
can "latch onto" the network request running on the server.
Now, in the browser, once that component renders, 1. is likely to already have resolved because it has been suspended that time on the server. So, no more "ongoing network request" and the value is already in the cache.
Now, we get to your problem: components in the browser have no knowledge that they rendered on the server before. They just get mounted and behave as such. The cache will already be filled, but you apply 'cache-and-network'
, so they make a request anyways.
The best you could do here really is to use 'cache-first'
- but of course, during the runtime of your application, that will not be satisfying.
I don't really have a good suggestion here, but maybe as a workaround you could have some kind of global recentlyLoaded
variable that changes from true
to false
after 30 seconds, and only after that, your default fetchPolicy
changes from cache-first
to 'cache-and-network'
?
@phryneas How do you recommend changing the default fetchPolicy
? It doesn't appear that fetchPolicy
supports a callback fn like nextFetchPolicy
does.
Or are you recommending something like:
const client = useApolloClient()
useEffect(() => {
setTimeout(() => {
client.defaultOptions.watchQuery.fetchPolicy = 'cache-and-network';
}, 30000)
}, [])
Yes, I believe that should work.
Our goal with apollo client is to configure the following behavior:
We use the following watchQuery options which implements the above in a fully client-side rendered environment.
However, now we're starting to incorporate SSR rendering of client components using
useSuspenseQuery
.What I think should happen is that the SSR pass should use
fetchPolicy: 'cache-and-network'
and then once the client hydrates the first (and subsequent) render(s) would usenextFetchPolicy
until the component is unmounted and remounted at which point we'd start back atfetchPolicy
.We observe in practice is a duplicate fetch for each query since one fetch occurs during SSR and the other during CSR. It looks like
fetchPolicy/nextFetchPolicy
application is not preserved across the server/client boundary. Is this intended behavior? Am I thinking about the implementation offetchPolicy/nextFetchPolicy
correctly? For full transparency I find the docs on fetchPolicy/nextFetchPolicy a bit confusing. It's not totally clear what constitutes an "execution" 🙈As always, thanks for any help / thoughts you have!