fix(query-core): resolve suspense when query data is set programmatically#11036
fix(query-core): resolve suspense when query data is set programmatically#11036AmariahAK wants to merge 3 commits into
Conversation
…ally When useSuspenseQuery is used and setQueryData populates the cache while a fetch is in-flight, the suspense boundary stays stuck on the original fetch promise. This prevents streamedQuery and manual cache updates from releasing suspense. Modify fetchOptimistic in queryObserver to use Promise.race between the fetch promise and a cache subscriber that listens for 'updated' events. When data appears in the cache via setQueryData or a streamed chunk, the race resolves immediately without aborting the fetch. This allows the suspense boundary to release and show the available data while the fetch continues in the background. Closes TanStack#10924 Co-authored-by: atlarix-agent <agent@atlarix.dev>
Co-authored-by: atlarix-agent <agent@atlarix.dev>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthrough
ChangesSuspense Resolution Fix
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant QueryObserver
participant QueryFn
participant QueryCache
QueryObserver->>QueryFn: query.fetch()
QueryObserver->>QueryCache: subscribe(updated)
alt cache data arrives first
QueryCache-->>QueryObserver: updated event with data
QueryObserver->>QueryCache: unsubscribe()
QueryObserver-->>QueryObserver: createResult()
else fetch completes first
QueryFn-->>QueryObserver: fetch resolved
QueryObserver->>QueryCache: unsubscribe()
QueryObserver-->>QueryObserver: createResult()
end
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 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 |
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 0f9c9f6e-0fdd-44e8-b976-3179c1f4098f
📒 Files selected for processing (3)
.changeset/resolve-suspense-setquerydata.mdpackages/query-core/src/queryObserver.tspackages/react-query/src/__tests__/useSuspenseQuery.test.tsx
…h rejection unsubscribe() was only called in the .then() success path. If query.fetch() rejected before the cache subscriber resolved the race, the subscription leaked — staying registered on QueryCache indefinitely and checking a stale queryHash on every 'updated' event. Use .finally() to ensure unsubscribe() runs on both success and rejection, preserving the original promise type through the chain. Co-authored-by: atlarix-agent <agent@atlarix.dev>
PR Description
@tanstack/query-core:test:lib → 546 passed, 0 failures
@tanstack/react-query:test:lib → 567 passed, 0 failures