-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Avoid making network requests when skip is true #6752
Conversation
Great Job, we were just having that issue right now ❤️ |
4486e89
to
96cbea3
Compare
result: { data }, | ||
newData: () => ({ data: nextData }) | ||
}) | ||
mockSingleLink( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test was behaving flakily due to its use of MockedProvider
's newData
function, which is kinda broken. I've adjusted the test to be more specific about the mocked requests it's working with, and added a few quick notes about the full workflow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm okay with this conservative change/bugfix for 3.1.2, but I would really love to see the previous data delivered at some point, perhaps even in 3.2.0.
When skip is set to true but other updated options have been passed into `useQuery` (like updated variables), `useQuery` will still make a network request, even though it will skip the handling of the response. This commit makes sure `useQuery` doesn't make unnecessary `skip` network requests. Fixes #6670 Fixes #6190 Fixes #6572
// NOTE: We no longer think this is the correct behavior. Skipping should | ||
// not automatically set `data` to `undefined`, but instead leave the | ||
// previous data in place. In other words, skipping should not mandate | ||
// that previously received data is all of a sudden removed. Unfortunately, | ||
// changing this is breaking, so we'll have to wait until Apollo Client | ||
// 4.0 to address this. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
I used the logic to create a query by setting skip to true and use refetch only at the desired timing. After this patch, this logic no longer works with following error. Is this the intended situation?
|
@@ -227,6 +227,8 @@ export class QueryData<TData, TVariables> extends OperationData { | |||
} | |||
|
|||
private updateObservableQuery() { | |||
if (this.getOptions().skip) return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently, when the first option starts with skip: true, there is a problem that refetch is not ready and cannot be executed. How about changing the order as follows?
private updateObservableQuery() {
// If we skipped initially, we may not have yet created the observable
if (!this.currentObservable) {
this.initializeObservableQuery();
return;
}
if (this.getOptions().skip) return;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not that this isn't a bug, but isn't an initial state with skip: true what lazy query is for?
ie
const [runQuery, response] = useLazyQuery(myQuery);
useEffect(() => {
if (!skip) {
runQuery();
}
}, [skip]);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since there is no clear guidance on this in the official documents, a lot of users will think and use just like me. It is not easy to think of 'skip' affecting 'refetch' without any explanation.
And I can do it as you explained, but it has already become a strangely shaped code. And useLazyQuery's refetch function returns void, so we need to add more useEffect to use the response. The return value of useQuery's refetch is a promise, so you can use data directly with async/await. It's confusing why it was designed this way, but not all of these relationships seem clear and consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just had exactly the same issue as you @gtolarc and was also using useQuery
to get refetch
because useLazyQuery
returns void instead of a promise.
I'd be in favor of init the observable as well, as this change is quite breaking for a lot of people I guess 😕
i've confirmed that updating to 3.1.3 in my project solves my skip-related issue perhaps also solved apollographql/react-apollo#3492 |
@shrugs Upgrade 3.1.3 does not solve the problem that SKIP is true and still requests the network |
Can confirm that this issue is still there in 3.1.4 and 3.2.0 |
Also still seeing this on 3.2.0. |
For anyone having the same problem (everybody), here's a custom import { useEffect } from 'react';
import { useLazyQuery } from '@apollo/client';
// The default Apollo's useQuery hook ignores the `skip` option if it's
// set to true the first time the hook is processed
export function useQuery(query, options) {
const [execQuery, result] = useLazyQuery(query, options);
useEffect(() => {
if (options.skip !== true) {
execQuery();
}
}, [execQuery, options.skip]);
return result;
} |
This custom hook only seems to work if you don't need refetch or other useQuery capabilities.
|
When skip is set to true but other updated options have been passed into
useQuery
(like updated variables),useQuery
will still make a network request, even though it will skip the handling of the response. This commit makes sureuseQuery
doesn't make unnecessaryskip
network requests.Fixes #6670
Fixes #6190
Fixes #6572