apollographql / apollo-client

:rocket:  A fully-featured, production ready caching GraphQL client for every UI framework and GraphQL server.
https://apollographql.com/client
MIT License
19.38k stars 2.66k forks source link

Refetch doesn't update all the places that used same useQuery (breaking change in 3.5.0) #9307

Open JakubJagoda opened 2 years ago

JakubJagoda commented 2 years ago

Hello folks. Our code broke after updating @apollo/client from 3.4.17 to 3.5 (tested both 3.5.0 and 3.5.7, both broken) so we think it might be a bug (or we've been misusing the client the whole - I want to find that out).

Intended outcome: We're using client-side GraphQL approach, similar to the one presented here: https://github.com/hasura/client-side-graphql

We have a custom hook (let's call it useGetUser) that fetches the logged in user data (basically a wrapper around useQuery with caching policies ({ fetchPolicy: 'network-only', nextFetchPolicy: 'cache-only'}) and a custom client-side resolver that matches the query. This resolver looks for a specific cookie before making a request and if it's not found, it throws (causing the useQuery to return an error). The useGetUser hook also returns refetch function directly from useQuery, so that when the cookie is found, we could call it and cause the query to be refetched and in effect we would have all the components updated.

It was working fine in 3.4.17 and after refetching every place using useGetUser would be correctly re-rendered with the data that the resolver would now return.

Actual outcome:

3.5.x breaks this behavior. Only one of the components re-renders and the others are still in the previous errored state, even though the data has been refetched. It works either if we downgrade back to 3.4.17 or remove caching policies from useGetUser hook.

How to reproduce the issue:

I have set a simple repo to reproduce the problem here: https://github.com/JakubJagoda/apollo-client-bug-test (it's a simple app based on CRA. Sorry, I tried set it up in codesandbox, but it kept hanging after adding @graphql-tools/schema).

The step to reproduce is to

  1. run the app
  2. see that there are 2 error messages
  3. click the button
  4. one of the messages turns into the success and the other still show error

In 3.4.x after clicking the button, both messages would turn to success. So let's talk about what's going on here:

As you can see we have a custom useGetMessage hook wrapping useQuery with caching policies and returning some of the members that useQuery returned, including refetch function. The query will make its way to a client-side resolver, which is, depending on outer conditions (for simplicity of the example it's a global variable window.__SOMETHING__), either going to return something or throw (the latter being default, i.e. it's going to throw until the outer conditions change). There are two components using the useGetMessage hook. For the sake of example's simplicity, one of them has a button that will cause the global variable to be modified and then will call the refetch. The query should now be performed again, but this time the resolver is going to return some data, rather than throwing. But only one of the components is updated, the other one still shows the error state.

If you now change the @apollo/client version to 3.4.17, re-run the app and perform the steps again, you will see 2 success messages rather than 1, meaning both components using useGetMessage got fresh data. It is also going to work in 3.5.x if you remove the caching policies, but we wanted to reduce the number of calls as the hook is going to appear in few places, that's why we use cache.

Please let us know if this is a bug or it's a use case that we've been doing wrong and it only worked before by accident. Much thanks!

Versions

System: OS: Windows 10 10.0.19043 Binaries: Node: 14.17.0 - C:\Program Files\nodejs\node.EXE Yarn: 1.22.17 - C:\Program Files\nodejs\yarn.CMD npm: 6.14.13 - C:\Program Files\nodejs\npm.CMD Browsers: Chrome: 97.0.4692.71 Edge: Spartan (44.19041.1023.0), Chromium (97.0.1072.55) npmPackages: @apollo/client: 3.5.7 => 3.5.7

ivansky commented 2 years ago

The same issue here, I hope someone could start working on it or at least take a look once.