Skip to content

Feature/use suspense queries combine#10576

Merged
TkDodo merged 5 commits intomainfrom
feature/useSuspenseQueries-combine
Apr 25, 2026
Merged

Feature/use suspense queries combine#10576
TkDodo merged 5 commits intomainfrom
feature/useSuspenseQueries-combine

Conversation

@TkDodo
Copy link
Copy Markdown
Collaborator

@TkDodo TkDodo commented Apr 25, 2026

fixes #10129

Summary by CodeRabbit

  • Bug Fixes

    • Corrected Suspense behavior during query resets so combined query results and listener notifications no longer trigger unnecessary recomputations when queries suspend.
  • Tests

    • Added unit and integration tests validating Suspense/reset interactions and ensuring combine callbacks are not invoked during suspension phases.
  • Chores

    • Added a changeset to publish a patch release.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 25, 2026

📝 Walkthrough

Walkthrough

Adds a suspense-aware guard in QueriesObserver to skip recomputing combine when matched suspense queries have undefined data, plus tests and a changeset documenting the patch release.

Changes

Cohort / File(s) Summary
Changesets Entry
​.changeset/wild-rabbits-jump.md
Adds changeset metadata documenting a patch bump for @tanstack/react-query / @tanstack/query-core and noting the Suspense-related fix to skip combine when queries would suspend.
Core Observer Logic
packages/query-core/src/queriesObserver.ts
Adds #shouldSkipCombine() and updates #notify() to reuse previousResult (skip #combineResult) when a matched observer has options.suspense and tracked result data === undefined; ensures listeners are still notified when skipping combine.
Observer Tests
packages/query-core/src/__tests__/queriesObserver.test.tsx
Adds two tests asserting QueriesObserver does not re-invoke combine after resetQueries causes suspense (one for initially-suspense queries, one for toggled suspense via setQueries).
React Suspense Tests
packages/react-query/src/__tests__/useSuspenseQueries.test.tsx
Adds a test covering useSuspenseQueries during queryClient.resetQueries() with a pending suspense query, asserting no synchronous throw, error boundary behavior after pending error, and that combine is not improperly invoked during the suspend phase.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I hopped through queries, quiet and spry,
When data went missing I did not try
To mash results together in vain —
I kept the old answer, spared the pain.
Hooray for gentle suspends! 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (2 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description only contains an issue reference ('fixes #10129') and completely omits all required template sections including the Changes section and Release Impact checklist. Complete the PR description by filling out all template sections: add a detailed Changes section explaining what was fixed, and mark the appropriate Release Impact checkbox indicating this affects published code and has a changeset.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title is vague and uses forward-slash formatting ('Feature/use suspense queries combine') that doesn't clearly convey the specific fix or change being made. Revise the title to clearly describe the main change, such as 'Skip combine notification when queries suspend' or 'Fix combine callback invocation in useSuspenseQueries to respect type contract'.
✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check ✅ Passed All code changes directly address the root cause in issue #10129: #shouldSkipCombine() in queriesObserver.ts prevents combine invocation during suspend states, matching the type contract that combine receives only successful query data.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the combine behavior in useSuspenseQueries: the implementation change, corresponding unit tests, and integration test are all focused on the suspend/combine issue with no unrelated modifications.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/useSuspenseQueries-combine

Comment @coderabbitai help to get the list of available commands and usage tips.

@TkDodo TkDodo marked this pull request as ready for review April 25, 2026 10:16
@nx-cloud
Copy link
Copy Markdown

nx-cloud Bot commented Apr 25, 2026

View your CI Pipeline Execution ↗ for commit 5cb48ea

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

☁️ Nx Cloud last updated this comment at 2026-04-25 10:44:45 UTC

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 25, 2026

🚀 Changeset Version Preview

2 package(s) bumped directly, 22 bumped as dependents.

🟩 Patch bumps

Package Version Reason
@tanstack/query-core 5.100.2 → 5.100.3 Changeset
@tanstack/react-query 5.100.2 → 5.100.3 Changeset
@tanstack/angular-query-experimental 5.100.2 → 5.100.3 Dependent
@tanstack/angular-query-persist-client 5.100.2 → 5.100.3 Dependent
@tanstack/eslint-plugin-query 5.100.2 → 5.100.3 Dependent
@tanstack/preact-query 5.100.2 → 5.100.3 Dependent
@tanstack/preact-query-devtools 5.100.2 → 5.100.3 Dependent
@tanstack/preact-query-persist-client 5.100.2 → 5.100.3 Dependent
@tanstack/query-async-storage-persister 5.100.2 → 5.100.3 Dependent
@tanstack/query-broadcast-client-experimental 5.100.2 → 5.100.3 Dependent
@tanstack/query-devtools 5.100.2 → 5.100.3 Dependent
@tanstack/query-persist-client-core 5.100.2 → 5.100.3 Dependent
@tanstack/query-sync-storage-persister 5.100.2 → 5.100.3 Dependent
@tanstack/react-query-devtools 5.100.2 → 5.100.3 Dependent
@tanstack/react-query-next-experimental 5.100.2 → 5.100.3 Dependent
@tanstack/react-query-persist-client 5.100.2 → 5.100.3 Dependent
@tanstack/solid-query 5.100.2 → 5.100.3 Dependent
@tanstack/solid-query-devtools 5.100.2 → 5.100.3 Dependent
@tanstack/solid-query-persist-client 5.100.2 → 5.100.3 Dependent
@tanstack/svelte-query 6.1.21 → 6.1.22 Dependent
@tanstack/svelte-query-devtools 6.1.21 → 6.1.22 Dependent
@tanstack/svelte-query-persist-client 6.1.21 → 6.1.22 Dependent
@tanstack/vue-query 5.100.2 → 5.100.3 Dependent
@tanstack/vue-query-devtools 6.1.21 → 6.1.22 Dependent

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Apr 25, 2026

More templates

@tanstack/angular-query-experimental

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

@tanstack/eslint-plugin-query

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

@tanstack/preact-query

npm i https://pkg.pr.new/@tanstack/preact-query@10576

@tanstack/preact-query-devtools

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

@tanstack/preact-query-persist-client

npm i https://pkg.pr.new/@tanstack/preact-query-persist-client@10576

@tanstack/query-async-storage-persister

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

@tanstack/query-broadcast-client-experimental

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

@tanstack/query-core

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

@tanstack/query-devtools

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

@tanstack/query-persist-client-core

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

@tanstack/query-sync-storage-persister

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

@tanstack/react-query

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

@tanstack/react-query-devtools

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

@tanstack/react-query-next-experimental

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

@tanstack/react-query-persist-client

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

@tanstack/solid-query

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

@tanstack/solid-query-devtools

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

@tanstack/solid-query-persist-client

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

@tanstack/svelte-query

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

@tanstack/svelte-query-devtools

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

@tanstack/svelte-query-persist-client

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

@tanstack/vue-query

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

@tanstack/vue-query-devtools

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

commit: 5cb48ea

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 25, 2026

size-limit report 📦

Path Size
react full 12.1 KB (+0.35% 🔺)
react minimal 9.06 KB (0%)

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/query-core/src/queriesObserver.ts`:
- Around line 252-261: The guard in `#shouldSkipCombine` reads suspense from
cached this.#observerMatches[].defaultedQueryOptions which can be stale; change
it to read the current suspense flag from the live options or recompute the
match for the specific index. Specifically, update `#shouldSkipCombine` to use
this.#options (the current options array) for the suspense check (e.g.
this.#options?.queries[index]?.suspense or the equivalent shape your API uses)
or call the routine that produces an up-to-date defaultedQueryOptions for that
index instead of referencing this.#observerMatches.defaultedQueryOptions, while
keeping the existing this.#result[index]?.data check.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6da215a7-ff54-4f3f-be87-4883532d7c8a

📥 Commits

Reviewing files that changed from the base of the PR and between 93b2845 and a9d1a5d.

📒 Files selected for processing (4)
  • .changeset/wild-rabbits-jump.md
  • packages/query-core/src/__tests__/queriesObserver.test.tsx
  • packages/query-core/src/queriesObserver.ts
  • packages/react-query/src/__tests__/useSuspenseQueries.test.tsx

Comment thread packages/query-core/src/queriesObserver.ts
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/query-core/src/__tests__/queriesObserver.test.tsx`:
- Around line 503-504: The test calls queryClient.resetQueries({ queryKey: key
}) and immediately asserts combine was called, which can race with
queued/batched notify delivery; fix by flushing pending notifications after
resetQueries before asserting: either wrap the reset in React's act (e.g.,
act(() => { queryClient.resetQueries({ queryKey: key }) })) or await a
microtask/macrotask drain (e.g., await Promise.resolve() or await new
Promise(setImmediate)) right after calling queryClient.resetQueries and before
expect(combine).toHaveBeenCalledTimes(1), and apply the same change for the
second occurrence around line 546/547.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9826816e-9182-4144-82dd-b9003c51afad

📥 Commits

Reviewing files that changed from the base of the PR and between a9d1a5d and 5cb48ea.

📒 Files selected for processing (2)
  • packages/query-core/src/__tests__/queriesObserver.test.tsx
  • packages/query-core/src/queriesObserver.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/query-core/src/queriesObserver.ts

Comment thread packages/query-core/src/__tests__/queriesObserver.test.tsx
@TkDodo TkDodo merged commit f85d825 into main Apr 25, 2026
8 checks passed
@TkDodo TkDodo deleted the feature/useSuspenseQueries-combine branch April 25, 2026 10:55
@github-actions github-actions Bot mentioned this pull request Apr 25, 2026
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.

useSuspenseQueries combine is called with pending/error results despite types implying data is always defined

1 participant