-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
fix(react-query/HydrationBoundary): prevent unnecessary refetch during hydration #9968
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
base: main
Are you sure you want to change the base?
fix(react-query/HydrationBoundary): prevent unnecessary refetch during hydration #9968
Conversation
🦋 Changeset detectedLatest commit: 78ce3f5 The changes in this PR will be included in the next version bump. This PR includes changesets to release 19 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
📝 WalkthroughWalkthroughAdds hydration-aware tracking to prevent double-fetch during HydrationBoundary hydration: introduces a WeakSet to mark pending queries, updates QueryObserver to skip fetches for pending queries (unless forced), updates HydrationBoundary to mark/clear pending queries, adds docs, tests, and a changeset. Changes
Sequence Diagram(s)sequenceDiagram
participant App as App / Router
participant HB as HydrationBoundary
participant QC as QueryClient / Cache
participant QO as QueryObserver
participant Net as Network
rect rgba(230,240,255,0.5)
Note over App,HB: Render phase (sync)
App->>HB: Render with dehydrated state
HB->>QC: Hydrate cache (useMemo)
HB->>QC: For each hydrated query: add to pendingHydrationQueries
Note over HB,QC: Queries flagged as pending
end
rect rgba(220,255,230,0.5)
Note over QO,Net: Subscription / mount
QO->>QO: onSubscribe runs
QO->>QC: Check pendingHydrationQueries for query
alt pending and refetchOnMount != 'always'
QO->>QO: Skip initial fetch (avoid double-fetch)
else not pending or refetchOnMount == 'always'
QO->>Net: Fetch data
end
end
rect rgba(255,250,220,0.5)
Note over HB: Effect phase (async)
HB->>HB: useEffect runs after paint
HB->>QC: Complete hydration
HB->>QC: clear pendingHydrationQueries for hydrated queries
Note over HB,QC: Cleanup ensures no stale pending flags
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Comment |
|
View your CI Pipeline Execution ↗ for commit 78ce3f5
☁️ Nx Cloud last updated this comment at |
86745a3 to
8626d42
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #9968 +/- ##
==========================================
+ Coverage 36.86% 42.81% +5.94%
==========================================
Files 245 172 -73
Lines 11102 8278 -2824
Branches 2079 1687 -392
==========================================
- Hits 4093 3544 -549
+ Misses 6484 4344 -2140
+ Partials 525 390 -135 🚀 New features to boost your workflow:
|
cfa5d74 to
695fa28
Compare
…tract 'clearPendingQueries' function
|
Thanks a lot for this. I hope it gets merged soon 🤞 |
|
|
||
| > Note: Only `queries` can be dehydrated with an `HydrationBoundary`. | ||
| > Note: `HydrationBoundary` automatically prevents unnecessary refetching during hydration. Queries being hydrated will not trigger a refetch on mount, unless `refetchOnMount` is explicitly set to `'always'`. |
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.
Thank you for this PR! I've only had time to skim it so far and it will take some time before I can dig in properly, but I wanted to provide some quick feedback here.
We also need to account for the case where there is some time in between fetching on the server, and hydrating on the client. This commonly happens when the markup is cached, in which case the hydration can happen days after the fetch on the server. In this situation, we do want to render with the stale data initially (this is what the SSR pass did and we need to match it), but we also want to immediately refetch the data because it's stale.
|
|
||
| // WeakSet to track queries that are pending hydration | ||
| // Used to prevent double-fetching when HydrationBoundary defers hydration to useEffect | ||
| export const pendingHydrationQueries: WeakSet<Query<any, any, any, any>> = |
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 don't think we can use a global singleton to keep track of this, what if there are several queryClients? In that case a query might just be about to hydrate into one of these, not all of them.
Annoying as that is, I think we need to use a context for this. Note that there is some prior art with isRestoring.
🎯 Changes
Fixes #9610
When using
HydrationBoundarywith existing queries in the cache, an unnecessary refetch was triggered during hydration even though fresh data was about to be hydrated from the server.Root Cause
useQuery'sonSubscriberuns beforeHydrationBoundary'suseEffectcompletes hydrationSolution
pendingHydrationQueriesWeakSet to track queries pending hydrationuseMemo(before children render)queryObserver.onSubscribeif query is pending hydrationrefetchOnMount: 'always'still triggers refetch (user explicitly wants fresh data)useEffectafter hydration completesFiles Changed
packages/query-core/src/hydration.ts- ExportpendingHydrationQueriesWeakSetpackages/query-core/src/index.ts- Re-exportpendingHydrationQueriespackages/query-core/src/queryObserver.ts- Check pending hydration inonSubscribepackages/react-query/src/HydrationBoundary.tsx- Mark/clear pending hydration queries with cleanuppackages/react-query/src/__tests__/HydrationBoundary.test.tsx- Add 14 test casesdocs/framework/react/guides/ssr.md- Document new behaviordocs/framework/react/reference/hydration.md- Document new behavior✅ Checklist
pnpm run test:pr.🚀 Release Impact
Summary by CodeRabbit
Bug Fixes
Documentation
Tests
✏️ Tip: You can customize this high-level summary in your review settings.