fix(react-query): hydrate deferred queries before observers subscribe to avoid a redundant refetch - #11137
Open
ostapondo wants to merge 1 commit into
Open
Conversation
… to avoid a redundant refetch
Contributor
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthrough
ChangesHydrationBoundary hydration timing
Estimated code review effort: 3 (Moderate) | ~20 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🎯 Changes
Fixes #9610.
HydrationBoundarydefers hydration of queries that already exist in the cache to an effect, so that transitions don't update existing observers mid-render. ButuseQuery'suseSyncExternalStoresubscription is also a passive effect, and children's effects run before parents'. On a revisit (query cached but unmounted), the observer subscribes first, sees the old stale entry, and starts a refetch of the exact data the dehydrated state already contains — the server computes it in the loader and the client immediately fetches it again.This moves the deferred hydration (and the
optionsRefsync it reads) to a layout effect. All layout effects run before any passive effects, so hydration lands in the cache before any remounting observer decides whether to fetch. Layout effects still only run when the tree commits, so the aborted-transition behaviour is unchanged (the existing test for it stays green).Behaviour change worth noting: already-mounted observers now receive hydrated data at commit time rather than after paint. One timing assertion in an existing test was updated accordingly; the render-phase purity guarantee is still covered by the aborted-transition test.
Not covered: a
useSuspenseQueryover a query that is inpendingstate with no data starts its fetch during render, before any layout effect — that pre-existing path is unaffected by this change.Verified with a test that fails on
main(refetch fires, stale data rendered) and passes with the fix, plus a jsdom repro of the React Router loader flow from the issue against the built package.✅ Checklist
pnpm run test:pr.🚀 Release Impact
Summary by CodeRabbit
Bug Fixes
Tests