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

useSuspenseQueries made extra requests after fetching data #6491

Closed
angeloaltamiranom opened this issue Dec 5, 2023 · 4 comments
Closed

Comments

@angeloaltamiranom
Copy link
Contributor

Describe the bug

useSuspenseQueries will request data again right after receiving a response. As a side effect, this causes the result of useSuspenseQueries to change, which will trigger useEffects unnecessarily and under the right conditions, infinite query requesting.

Your minimal, reproducible example

https://codesandbox.io/p/sandbox/tanstack-query-bug-forked-gzjkr9?file=%2Fsrc%2FApp.js%3A30%2C56

Steps to reproduce

  1. use useSuspenseQueries and mock multiple requests with promises and setTimeout
  2. set a suspense boundary on the component that will the do the requesting
  3. console log the requests being done and the responses received
  4. reload the page and watch for the re-requesting of data

Expected behavior

I expect the data request to happen once.

How often does this bug happen?

Every time

Screenshots or Videos

No response

Platform

OS: MacOS
Browser: Chrome
Version: 119.0.6045.199

Tanstack Query adapter

react-query

TanStack Query version

5.12.2

TypeScript version

No response

Additional context

No response

@TkDodo
Copy link
Collaborator

TkDodo commented Dec 16, 2023

There is likely a problem with how we setup staleTime in suspense. Usually, with a single useSuspenseQuery, any small staleTime is "good enough", because the query suspends, and then the component renders immediately after the request returns. We set the staleTime to 1 second:

if (defaultedOptions.suspense) {
// Always set stale time when using suspense to prevent
// fetching again when directly mounting after suspending
if (typeof defaultedOptions.staleTime !== 'number') {
defaultedOptions.staleTime = 1000
}
}

to a avoid a refetch-on-mount here.

However, with useSuspenseQueries, we suspend until all queries have finished. Now the first query might finish fast, but the others take a longer time, in which case there will be a refetch for the first query because when the component that uses it finally mounts, more than staleTime time has passed already.

Your example though is flawed. You only see two useEffect calls because of StrictMode. data is stable. But we can reproduce the issue I'm talking about if we set the timeout to a higher value than the default staleTime, in which case we will see Call query N more than once. This is what I would phrase as an issue, not the multiple effects being called. Your example actually doesn't show multiple requests being made, at least for me 😅

Here's a fork with what I mean.

  • StrictMode is turned off, so only one effect
  • staleTime is 500ms
  • timeout for requests is 1.5s

The log output I'm seeing is:

Call query 1
Call query 2
Call query 3
Fallback
Call query 1
Call query 2
result 1 changed to:  [1]
result 2 changed to:  [2]
result 3 changed to:  [3]

This is exactly because of the staleTime refetch you get on mount. query 3 only fetches once because it finishes last. The expected output imo would be:

Call query 1
Call query 2
Call query 3
Fallback
result 1 changed to:  [1]
result 2 changed to:  [2]
result 3 changed to:  [3]

However, I don't really know how we can reliably prevent a refetch on the first mount after the query has suspended :(

@TkDodo
Copy link
Collaborator

TkDodo commented Dec 31, 2023

I think the best we can do right now is document that you should probably set a high enough staleTime so that queries won't refetchOnMount when the suspended component re-mounts when using useSuspenseQueries. Do you want to do that?

@angeloaltamiranom
Copy link
Contributor Author

Thanks for the explanation! I've created the following PR to update the docs: #6641

@TkDodo
Copy link
Collaborator

TkDodo commented Jan 5, 2024

we've documented the workaround, which is good enough right now imo.

@TkDodo TkDodo closed this as completed Jan 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants