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 and startTransition will trigger infinite query requesting #6498

Closed
angeloaltamiranom opened this issue Dec 6, 2023 · 9 comments · Fixed by #6611
Closed
Labels

Comments

@angeloaltamiranom
Copy link
Contributor

angeloaltamiranom commented Dec 6, 2023

Describe the bug

If you use startTransition to change any value used in a query of useSuspenseQueries you will get infinite query requesting.

Your minimal, reproducible example

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

Edit: Query cancellation was important for this bug to manifest: https://codesandbox.io/p/sandbox/infinite-query-retrying-example-9k2456?file=%2Fsrc%2FApp.js

Steps to reproduce

  1. Open the code sandbox
  2. Open the console
  3. Click on the set seed button
  4. Watch the infinite query requesting

Expected behavior

I expect not to get into the infinite requesting state.

How often does this bug happen?

Every time

Screenshots or Videos

Screen.Recording.2023-12-06.at.16.54.37.mov

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

Might be related to the following issues:

@angeloaltamiranom angeloaltamiranom changed the title useSuspenseQueries and startTransition will trigger infinite query requesting useSuspenseQueries and startTransition will trigger infinite query requesting Dec 6, 2023
@angeloaltamiranom
Copy link
Contributor Author

I was able to find a version in which this bug was no longer present v5.7.0. According to the changelog for version v5.7.1 there was one PR that dealt with code in useQueries: #6303 . Not clear why, but, might this be the reason for this bug?

CC: @maciej-baruch

Codesandbox for version v5.7.0 ( No bug present ): https://codesandbox.io/p/sandbox/playground-react-query-5w84fx?file=%2Fpackage.json%3A11%2C36

@maciej-baruch
Copy link
Contributor

maciej-baruch commented Dec 7, 2023

I'll write some tests and check this out.

@angeloaltamiranom @TkDodo This behavior was introduced in 5.8.6, in fcc0b28, as a solution to #6392:

observer.setQueries(
defaultedQueries,
options as QueriesObserverOptions<TCombinedResult>,
{
listeners: false,
},
)

I might look into that over the weekend if it is not solved by that time 🙃

@maciej-baruch
Copy link
Contributor

maciej-baruch commented Dec 11, 2023

@angeloaltamiranom So I wrote a couple of tests and ... I could not fail them, they all passed, there is seems to be nothing wrong with the lib.

Make sure your queryClient is static, do not recreate it every time your App function runs because this makes the QCP re-render each time a new client is constructed.

Instead of this:

export default function App() {

...

  return (
    <QueryClientProvider client={new QueryClient()}>

Do this:

const client = new QueryClient()

export default function App() {

...

  return (
    <QueryClientProvider client={client}>

@angeloaltamiranom
Copy link
Contributor Author

@maciej-baruch Good note. Sadly, your fix only addressed my minimal reproducible example, which maybe was too 'minimal' to show the real issue my team was encountering in our project.

In this codesandbox I have added query cancellation, and used your fix as well, and the issue is still visible: https://codesandbox.io/p/sandbox/infinite-query-retrying-example-9k2456?file=%2Fsrc%2FApp.js

@GabbeV
Copy link

GabbeV commented Dec 11, 2023

I seem to have this issue as well.
Here is a reproduction that resemble my code:
https://codesandbox.io/p/sandbox/quirky-knuth-8ns8dz?file=%2Fsrc%2FApp.tsx%3A8%2C41

After 5.8.6 the old query seem to be garbage collected before the new query is done causing the old query to get fetched again. While fetching the old query again the new query gets garbage collected causing it too loop forever unless the fetch happens to be faster than the gcTime.

Looking at the devtools i can see that before 5.8.6 the old query had an observer until the new query was done while after 5.8.6 the observer immediately disappears and the new query get an observer instead.

Attaching and detaching observers during render seems like a bad idea as react expect render to be a pure operation that it can rerun. Failing to rerun the old rerender here not only lead to the infinite loop but also cause the suspense fallback to get shown even though it shouldn't when the update is using a deferred value or is in a transition.

@TkDodo
Copy link
Collaborator

TkDodo commented Dec 29, 2023

I have a new fix that reverts the 5.8.6 changes and fixes that issue in a different way. Can you check if the codesandbox preview from this PR works for you?

basically, depend on:

"@tanstack/react-query": "https://pkg.csb.dev/TanStack/query/commit/0b33cd80/@tanstack/react-query",

and see if that fixes your issues, thanks

@GabbeV
Copy link

GabbeV commented Dec 29, 2023

Can't speak for the issue 5.8.6 solved but my codesandbox work as I expect if I change it to depend on 0b33cd8.

@TkDodo
Copy link
Collaborator

TkDodo commented Dec 29, 2023

Thx. The 5.8.6 issue is covered with tests so I'm quite sure it's also fixed in that version.

@TkDodo
Copy link
Collaborator

TkDodo commented Dec 29, 2023

@GabbeV thanks, I can see in your reproduction that your problem is actually the same as #6486 except that your old query gets gc'd in between

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants