Avoiding fallback component after initial load with `useSuspenseQuery` when automatically refreshing data

I’m trying to make a React context provider which runs a query, and then allows it’s children to render.

I was thinking it’d be nice to do this with Suspense, because I could have other providers that load essential data for the app, and it would all bubble up to the one boundary and allow me to show a loading spinner for everything without having loader spinners and logic to show the spinners dotted around all over the place.

I’ve made my provider, it fetches the data, and it shows the loading fallback just fine, but it seems like useSuspenseQuery is periodically refetching the data. This is also fine, I actually would prefer to keep that behaviour, the problem I’m having is that it is showing the Suspense fallback (i.e. full-screen loading component…) every time it decides to refetch that data automatically.

All of the guides for suspense I’ve use highlight how you can control this if you’re refetching yourself, but I’m not changing anything here - it’s just doing it on it’s own, so I’m not sure what I can wrap in a transition. There are no variables changing to defer, etc.

I’ve tried to use useDeferredValue on the data returned by the query to pass into the provider, but I think that doesn’t work and wouldn’t make sense because the Suspense boundary is above this component. I’ve also tried using different fetchPolicy and nextFetchPolicy values and have had no luck.

I’m quite new to Suspense in general, so apologies if there’s a really obvious solution to this, I’ve tried to read around the issue, but am just stumped right now. Any help would be much appreciated :slight_smile:

Have you tried to wrap the .refetch call in startTransition?

Aah, this is completely my own fault I’ve realised.

The periodic refetching is because I’m setting up the ApolloProvider in a wrapper so I can set up the client with a link to handle adding an Authorization header. This wrapper was using a hook (from Clerk in this case) which is causing the wrapper to re-render every time the refresh token updates. This was recreating the Apollo Client entirely every time that token was updated (every minute roughly…) and causing the cache the be destroyed along with it, meaning it was refetching “automatically”.

I’ve wrapped the client creation in a useMemo so I can still use the hook from Clerk, and it seems to have solved my issue. If I want to do a periodic refresh now, I’ll try wrapping refetch in startTransition.

Thanks!

1 Like