Skip to content

fix(query-core): avoid repeated event listener setup without cleanup - #12302

Open
blueDaydreaming725 wants to merge 1 commit into
TanStack:mainfrom
blueDaydreaming725:fix/manager-setup-without-cleanup
Open

blueDaydreaming725 wants to merge 1 commit into
TanStack:mainfrom
blueDaydreaming725:fix/manager-setup-without-cleanup

Conversation

@blueDaydreaming725

@blueDaydreaming725 blueDaydreaming725 commented Oct 23, 2026 •

Copy link
Copy Markdown

🎯 Changes

问题: FocusManager/OnlineManager 用 #cleanup 是否存在来判断 setup 是否已安装,但当 setup 返回 undefined(无需清理)时会被误判为“未安装”,导致每新增订阅者都重复执行 setup,造成多次注册监听器;在 FocusManager 中,一次外部事件会触发多次通知。

修复: 将 this.#cleanup = setup(...) ?? noop,用现有空函数兜底代替 undefined,使“已安装但无需清理”和“已安装且有清理逻辑”都能被正确标记,从而避免重复安装。

验证: 新增测试确认修复后 setup 只执行一次、焦点事件只通知一次,且全部退订后仍能正常重新初始化。query-core 共 1611 个测试通过,包含 3 个新增测试。

本地检查:pnpm run test:pr --parallel=1 --base=origin/main 成功,337 个任务通过(32 个复用 Nx 缓存)。Preact 示例的类型检查先在无 dist 的状态下执行,再由完整流程复用;该示例当前会把已有的 dist 压缩 JS 纳入类型检查,此 PR 未修改该配置。

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested code changes locally with pnpm run test:pr, or these tests do not apply to this pull request.
  • I have followed the AI contribution policy and fully understand the code in this pull request, including any code generated with AI assistance.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

Summary by CodeRabbit

  • Bug Fixes
    • Fixed custom focus and online event listeners being set up repeatedly when subscribers are added. Setup now remains active while subscribers are present and can run again after all subscribers unsubscribe.
    • Fixed focus event notifications so each subscriber is notified only once per dispatched event when custom listener setup does not provide cleanup.

@changeset-bot

changeset-bot Bot commented Oct 23, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: c321cfb

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 24 packages
Name Type
@tanstack/query-core Patch
@tanstack/angular-query-experimental Patch
@tanstack/lit-query Patch
@tanstack/preact-query Patch
@tanstack/query-async-storage-persister Patch
@tanstack/query-broadcast-client-experimental Patch
@tanstack/query-devtools Patch
@tanstack/query-persist-client-core Patch
@tanstack/query-sync-storage-persister Patch
@tanstack/react-query Patch
@tanstack/solid-query Patch
@tanstack/svelte-query Patch
@tanstack/vue-query Patch
@tanstack/preact-query-devtools Patch
@tanstack/preact-query-persist-client Patch
@tanstack/react-query-devtools Patch
@tanstack/solid-query-devtools Patch
@tanstack/svelte-query-devtools Patch
@tanstack/vue-query-devtools Patch
@tanstack/react-query-persist-client Patch
@tanstack/solid-query-persist-client Patch
@tanstack/svelte-query-persist-client Patch
@tanstack/react-query-next-experimental Patch
@tanstack/eslint-plugin-query Patch

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

@coderabbitai

coderabbitai Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
📥 Commits

Reviewing files that changed from the base of the PR and between 4ed6095 and c321cfb.

📒 Files selected for processing: 5
  • .changeset/legal-lamps-repeat.md
  • packages/query-core/src/__tests__/focusManager.test.tsx
  • packages/query-core/src/__tests__/onlineManager.test.tsx
  • packages/query-core/src/focusManager.ts
  • packages/query-core/src/onlineManager.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

📝 Walkthrough

FocusManager and OnlineManager now use a no-op cleanup when custom event-listener setup returns no cleanup function. Tests cover setup calls across subscriptions and focus event notifications.

Changes: Listener cleanup handling

Layer / File(s) Summary
Fallback cleanup and subscription behavior
packages/query-core/src/focusManager.ts, packages/query-core/src/onlineManager.ts, packages/query-core/src/__tests__/focusManager.test.tsx, packages/query-core/src/__tests__/onlineManager.test.tsx, .changeset/legal-lamps-repeat.md
Both managers store a no-op cleanup when setup returns undefined. Tests cover setup calls across subscriptions and focus event notifications. The changeset records a patch release for @tanstack/query-core.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested reviewers: sukvvon

Merge Risk: ⚪ Minimal · up to c321c

The change appears ready to merge after normal checks. Custom event-listener setups must return cleanup when they need their registrations removed.

Pre-merge checks: Passed 5
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main fix: preventing repeated event-listener setup when cleanup is absent.
Description check Passed The description explains the problem, implementation, validation results, checklist status, and release impact. It matches the required template and provides sufficient technical context.
Docstring Coverage Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 4…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 4 files. (1 skipped: 1 unsupported.)

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

❤️ Share

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

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant