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

skip: true and skipToken behave differently with useSuspenseQuery #12059

Open
epmatsw opened this issue Sep 5, 2024 · 1 comment
Open

skip: true and skipToken behave differently with useSuspenseQuery #12059

epmatsw opened this issue Sep 5, 2024 · 1 comment
Labels
🔍 investigate Investigate further

Comments

@epmatsw
Copy link

epmatsw commented Sep 5, 2024

Issue Description

I'm pretty sure this is a bug with skip: true, or at least skipToken behaves like I'd expect.

If you have a useSuspenseQuery that uses skip: boolean and toggles between true and false for that, it seems like sometimes the switch from true to false causes the query to skip the cache and suspend.

In the demo, you can quickly hit the button to toggle skipping on or off. Every once in a while, you can see the top one (skip: boolean) pop a suspend for a few frames, while the bottom one (skipToken) correctly re-reads from the cache.

Link to Reproduction

https://codesandbox.io/p/sandbox/lz67k5?file=%2Fsrc%2FApp.tsx%3A34%2C67

Reproduction Steps

No response

@apollo/client version

3.11.8

@jerelmiller
Copy link
Member

This is such an interesting one. Both skip: true and skipToken have almost the same code paths. It looks like the only difference is that we set some extra options for skip: true (not sure why to be honest). See how skipToken returns early while skip: true adds the extra options:

if (options === skipToken) {
return { query, fetchPolicy: "standby" };
}
const fetchPolicy =
options.fetchPolicy ||
client.defaultOptions.watchQuery?.fetchPolicy ||
"cache-first";
const watchQueryOptions = {
...options,
fetchPolicy,
query,
notifyOnNetworkStatusChange: false,
nextFetchPolicy: void 0,
};
if (__DEV__) {
validateOptions(watchQueryOptions);
}
// Assign the updated fetch policy after our validation since `standby` is
// not a supported fetch policy on its own without the use of `skip`.
if (options.skip) {
watchQueryOptions.fetchPolicy = "standby";
}

Other than this, both of these code paths rely on checking fetchPolicy: 'standby' in the downstream code which should avoid suspending (the __use hook is the thing that causes it to suspend):

const result = fetchPolicy === "standby" ? skipResult : __use(promise);

I'll have to dig into this further to understand where the difference is, but unfortunately won't have time to do so for a couple days. Thanks for raising the issue!

@jerelmiller jerelmiller added the 🔍 investigate Investigate further label Sep 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🔍 investigate Investigate further
Projects
None yet
Development

No branches or pull requests

2 participants