Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using fetchPolicy: 'cache-and-network' creates infinite loop #13

Closed
nicolaslopezj opened this issue Nov 8, 2018 · 6 comments
Closed

Comments

@nicolaslopezj
Copy link

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.

@trojanowski
Copy link
Owner

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.

@robertvansteen
Copy link

@trojanowski what's the reason it ignores the local cache? Is that a bug in react-apollo itself?

@trojanowski
Copy link
Owner

The infinite look was caused because:

  1. We were using the currentResult.partial flag to check if we had a full result in the cache:
    if (currentResult.partial) {
  2. This flag was always initially set to true if cache-and-network fetch policy was used, even if we had the full result.
  3. 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.

@nicolaslopezj
Copy link
Author

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

@namnm
Copy link

namnm commented May 13, 2019

@trojanowski Do you think the changes @nicolaslopezj can be merged?

@Yalian
Copy link

Yalian commented Jul 16, 2019

@trojanowski the changes was merged? or any support was added for this?

levindixon pushed a commit to levindixon/react-apollo-hooks that referenced this issue Aug 22, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants