fix(keep-alive): defer keep-alive branch updates while inactive#14708
fix(keep-alive): defer keep-alive branch updates while inactive#14708edison1105 wants to merge 3 commits intomainfrom
Conversation
close #12017 close vuejs/router#626 When a component update and a KeepAlive branch deactivation happen in the same flush, the deactivated branch can still finish its queued child update. In nested KeepAlive / keyed dynamic component cases, this can mount the next child twice: once in the deactivated cached branch and once in the newly active branch. Fix this by tracking deferred updates for inactive KeepAlive branches in the renderer and replaying them after the branch is activated again. This keeps the change scoped to KeepAlive branch activation state, preserves nested KeepAlive boundaries, and ensures re-activation applies the latest pending state.
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Size ReportBundles
Usages
|
@vue/compiler-core
@vue/compiler-dom
@vue/compiler-sfc
@vue/compiler-ssr
@vue/reactivity
@vue/runtime-core
@vue/runtime-dom
@vue/server-renderer
@vue/shared
vue
@vue/compat
commit: |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/runtime-core/src/renderer.ts (1)
2628-2642: Consider adding explicit return type annotation.The function works correctly, but adding an explicit return type improves code clarity and documentation:
📝 Suggested type annotation
export function setKeepAliveBranchActive( instance: ComponentInternalInstance, active: boolean, -): Set<ComponentInternalInstance> | undefined { +): Set<ComponentInternalInstance> | void { if (active) { const updates = deferredKeepAliveBranchUpdates.get(instance) deferredKeepAliveBranchUpdates.delete(instance) return updates } // Child updates will be collected under this inactive KeepAlive root. if (!deferredKeepAliveBranchUpdates.has(instance)) { deferredKeepAliveBranchUpdates.set(instance, new Set()) } + // Implicit void return when deactivating }Actually, looking closer the current signature
Set<ComponentInternalInstance> | undefinedis already present. The implementation is correct as-is.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/runtime-core/src/renderer.ts` around lines 2628 - 2642, No change required: the function setKeepAliveBranchActive already has an explicit return type annotation (Set<ComponentInternalInstance> | undefined) and the implementation matches that signature; leave the function declaration and body (including deferredKeepAliveBranchUpdates handling and returned updates) as-is.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@packages/runtime-core/src/renderer.ts`:
- Around line 2628-2642: No change required: the function
setKeepAliveBranchActive already has an explicit return type annotation
(Set<ComponentInternalInstance> | undefined) and the implementation matches that
signature; leave the function declaration and body (including
deferredKeepAliveBranchUpdates handling and returned updates) as-is.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: ccac7bfc-3604-45e4-9b8b-aba21ed6a30c
📒 Files selected for processing (3)
packages/runtime-core/__tests__/components/KeepAlive.spec.tspackages/runtime-core/src/components/KeepAlive.tspackages/runtime-core/src/renderer.ts
close #12017
close vuejs/router#626
When a component update and a KeepAlive branch deactivation happen in the same flush, the deactivated branch can still finish its queued child update. In nested KeepAlive / keyed dynamic component cases, this can mount the next child twice: once in the deactivated cached branch and once in the newly active branch.
Fix this by tracking deferred updates for inactive KeepAlive branches in the renderer and replaying them after the branch is activated again. This keeps the change scoped to KeepAlive branch activation state, preserves nested KeepAlive boundaries, and ensures re-activation applies the latest pending state.
Summary by CodeRabbit
Bug Fixes
Tests