Using fetchPolicy: 'cache-and-network' creates infinite loop
nicolaslopezj opened this issue ยท 6 comments
Using the options cache-and-network
for fetch policy creates an infinite loop.
I could see that in this if
:
query === previousQuery.current &&
isEqual(variables, previousVariables.current) &&
isEqual(apolloContextOptions, previousApolloContextOptions.current) &&
isEqual(restOptions, previousRestOptions.current)
previousVariables.current
and previousRestOptions.current
and always undefined.
I don't know why useRef is not persisting.
The infinite loop is caused by suspense. A component using the useQuery
hook with cache-and-network
fetch policy ignores local cache, starts fetching fresh data and throws a promise as a signal to react to suspend the tree. React then renders fallback and when data finishes loading tries to render the component again. But the cache is ignored again causing the loop. I created #15 which partially solves the problem - I'm emulating the cache-and-network
policy by using the default cache-first
one and then optionally forcing a refetch. The problem with that that the refetch is also invoked the first time the page is loading.
I also added a workaround in db119e5. You can now invoke the hook as useQuery(THE_QUERY, { suspend: false })
and manage the loading state by yourself, similar to how react-apollo does. It's published in the 0.1.5 version.
@trojanowski what's the reason it ignores the local cache? Is that a bug in react-apollo
itself?
The infinite look was caused because:
- We were using the
currentResult.partial
flag to check if we had a full result in the cache:react-apollo-hooks/src/useQuery.ts
Line 200 in 31d4f97
- This flag was always initially set to
true
ifcache-and-network
fetch policy was used, even if we had the full result. - Because of 2. React suspended the tree what caused the hook to be "restarted" and a new
observableQuery
was created (in a loop).
We should be able to emulate cache-and-network
by ourselves (I tried it in #15), but it's not a priority for me (but I'd accept a PR).
I'm going to close this issue because the loop doesn't happen in the non-suspense mode, and it's not currently possible to use it with suspend: true
(there's an error thrown in that case). I added a lack of support for non-standard fetch policies to the known suspense-only issues in #88.
I've made a rewrite of your useQuery hook and it works with any fetchPolicy, you can check it here https://github.com/nicolaslopezj/apollo-hooks/blob/master/src/useQueryBase.js
@trojanowski Do you think the changes @nicolaslopezj can be merged?
@trojanowski the changes was merged? or any support was added for this?