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).
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
run the app
see that there are 2 error messages
click the button
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!
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 arounduseQuery
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 theuseQuery
to return an error). TheuseGetUser
hook also returnsrefetch
function directly fromuseQuery
, 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 fromuseGetUser
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
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 wrappinguseQuery
with caching policies and returning some of the members thatuseQuery
returned, includingrefetch
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 variablewindow.__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 theuseGetMessage
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 therefetch
. 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 to3.4.17
, re-run the app and perform the steps again, you will see 2 success messages rather than 1, meaning both components usinguseGetMessage
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