Skip to content

Fix misc hydration bugs #9157

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

Merged
merged 5 commits into from
May 22, 2025
Merged

Conversation

Ephem
Copy link
Collaborator

@Ephem Ephem commented May 16, 2025

This PR:

  • Fixes Maximum update depth exceeded #8677 - A bug where hydrating failed queries (and possibly other conditions) could result in an infinite loop
  • Fixes an undocumented bug where an old promise could overwrite newer data
  • Fixes an undocumented bug where if a promise finished fast and was delivered as a synchronous thenable before React markup hydration, React Query would not hydrate it synchronously.
    • The effect would be that a page would show its full content, but revert to the Suspense state on hydration because the data was not available in the React Query cache, only to immediately show the full content again.
    • This behaviour also seem to have slowed down the initial load of pages with very fast APIs somewhat, so should be snappier now.
  • Implements tests for these bugs

At the point of hydrating a promise, we don't know when the promise will finish, that is, we don't know the dataUpdatedAt of the hydrated query, so we can't compare that to the existing query. The PR sidesteps this by introducing dehydratedAt as an approximation. This is not perfect, but is an improvement.

To fix the infinite loop bug I also opted to never hydrate promises if the existing query is already pending, as there is no way to know which of these pending queries will finish first or have the newest data. We could do fancier things like a Promise.race and use whatever finishes first, but that seemed like overengineering at this point.

* Do not hydrate older promises
* Do not infinite loop on hydrating failed promises
* Hydrate already resolved promises immediately
Copy link

nx-cloud bot commented May 16, 2025

View your CI Pipeline Execution ↗ for commit fd7a6e0.

Command Status Duration Result
nx affected --targets=test:sherif,test:knip,tes... ✅ Succeeded 49s View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 1s View ↗

☁️ Nx Cloud last updated this comment at 2025-05-22 15:33:47 UTC

Copy link

pkg-pr-new bot commented May 16, 2025

More templates

@tanstack/angular-query-devtools-experimental

npm i https://pkg.pr.new/@tanstack/angular-query-devtools-experimental@9157

@tanstack/angular-query-experimental

npm i https://pkg.pr.new/@tanstack/angular-query-experimental@9157

@tanstack/eslint-plugin-query

npm i https://pkg.pr.new/@tanstack/eslint-plugin-query@9157

@tanstack/query-broadcast-client-experimental

npm i https://pkg.pr.new/@tanstack/query-broadcast-client-experimental@9157

@tanstack/query-async-storage-persister

npm i https://pkg.pr.new/@tanstack/query-async-storage-persister@9157

@tanstack/query-core

npm i https://pkg.pr.new/@tanstack/query-core@9157

@tanstack/query-devtools

npm i https://pkg.pr.new/@tanstack/query-devtools@9157

@tanstack/query-persist-client-core

npm i https://pkg.pr.new/@tanstack/query-persist-client-core@9157

@tanstack/query-sync-storage-persister

npm i https://pkg.pr.new/@tanstack/query-sync-storage-persister@9157

@tanstack/react-query

npm i https://pkg.pr.new/@tanstack/react-query@9157

@tanstack/react-query-devtools

npm i https://pkg.pr.new/@tanstack/react-query-devtools@9157

@tanstack/react-query-next-experimental

npm i https://pkg.pr.new/@tanstack/react-query-next-experimental@9157

@tanstack/react-query-persist-client

npm i https://pkg.pr.new/@tanstack/react-query-persist-client@9157

@tanstack/solid-query

npm i https://pkg.pr.new/@tanstack/solid-query@9157

@tanstack/solid-query-devtools

npm i https://pkg.pr.new/@tanstack/solid-query-devtools@9157

@tanstack/solid-query-persist-client

npm i https://pkg.pr.new/@tanstack/solid-query-persist-client@9157

@tanstack/svelte-query

npm i https://pkg.pr.new/@tanstack/svelte-query@9157

@tanstack/svelte-query-devtools

npm i https://pkg.pr.new/@tanstack/svelte-query-devtools@9157

@tanstack/svelte-query-persist-client

npm i https://pkg.pr.new/@tanstack/svelte-query-persist-client@9157

@tanstack/vue-query

npm i https://pkg.pr.new/@tanstack/vue-query@9157

@tanstack/vue-query-devtools

npm i https://pkg.pr.new/@tanstack/vue-query-devtools@9157

commit: fd7a6e0

@Ephem Ephem marked this pull request as draft May 16, 2025 15:26
* Include dehydratedAt and ignore hydrating old promises
  * This is an approximation of dataUpdatedAt, but is not perfect
* Refactor checks for if we should hydrate promises or not to fix infinite loop bug on failed queries
* Hydrate already resolved promises synchronously
@Ephem Ephem force-pushed the fredrik/fix-hydration-bugs branch from 27d8d67 to 13c3232 Compare May 16, 2025 16:14
Copy link

codecov bot commented May 16, 2025

Codecov Report

Attention: Patch coverage is 94.44444% with 2 lines in your changes missing coverage. Please review.

Project coverage is 59.46%. Comparing base (065b5f4) to head (fd7a6e0).
Report is 2 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##             main    #9157       +/-   ##
===========================================
+ Coverage   45.00%   59.46%   +14.46%     
===========================================
  Files         206      138       -68     
  Lines        8219     5482     -2737     
  Branches     1836     1471      -365     
===========================================
- Hits         3699     3260      -439     
+ Misses       4080     1925     -2155     
+ Partials      440      297      -143     
Components Coverage Δ
@tanstack/angular-query-devtools-experimental ∅ <ø> (∅)
@tanstack/angular-query-experimental 85.04% <ø> (ø)
@tanstack/eslint-plugin-query ∅ <ø> (∅)
@tanstack/query-async-storage-persister 43.85% <ø> (ø)
@tanstack/query-broadcast-client-experimental 24.39% <ø> (ø)
@tanstack/query-codemods ∅ <ø> (∅)
@tanstack/query-core 97.89% <93.75%> (-0.10%) ⬇️
@tanstack/query-devtools 3.56% <ø> (ø)
@tanstack/query-persist-client-core 78.32% <ø> (ø)
@tanstack/query-sync-storage-persister 84.61% <ø> (ø)
@tanstack/query-test-utils ∅ <ø> (∅)
@tanstack/react-query 95.98% <100.00%> (+0.63%) ⬆️
@tanstack/react-query-devtools 10.00% <ø> (ø)
@tanstack/react-query-next-experimental ∅ <ø> (∅)
@tanstack/react-query-persist-client 100.00% <ø> (ø)
@tanstack/solid-query 78.20% <ø> (ø)
@tanstack/solid-query-devtools ∅ <ø> (∅)
@tanstack/solid-query-persist-client 100.00% <ø> (ø)
@tanstack/svelte-query 88.15% <ø> (ø)
@tanstack/svelte-query-devtools ∅ <ø> (∅)
@tanstack/svelte-query-persist-client 100.00% <ø> (ø)
@tanstack/vue-query 70.85% <ø> (ø)
@tanstack/vue-query-devtools ∅ <ø> (∅)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Ephem Ephem marked this pull request as ready for review May 16, 2025 17:20
Comment on lines 101 to 102
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
?.catch(() => {})
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using noop from query-core should get rid of the eslint-disable:

Suggested change
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
?.catch(() => {})
?.catch(noop)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't get rid of the lint warning unfortunately, that's warning about the "unnecessary" ?. here (this is typed as a promise, but might be a kind of thenable without .catch).

Still a good idea to use the noop, and I updated the comment to mention .catch specifically to make it a tiny bit clearer.

@TkDodo TkDodo merged commit 9f5fba3 into TanStack:main May 22, 2025
7 checks passed
@tlazarov-whiskypartners
Copy link

tlazarov-whiskypartners commented May 23, 2025

Is this going to be a part of next release?

@TkDodo
Copy link
Collaborator

TkDodo commented May 23, 2025

It's already released

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

Successfully merging this pull request may close these issues.

Maximum update depth exceeded
3 participants