fix(teleport): don't move teleport children if in pending mount#14702
fix(teleport): don't move teleport children if in pending mount#14702lichunju1 wants to merge 2 commits intovuejs:mainfrom
Conversation
📝 WalkthroughWalkthroughFixes a regression in Vue 3.5.32 where disabled Teleports containing component children inside Suspense-wrapped async components cause null reference errors. Modifies Teleport's deferred mount logic to use parentNode for correct container selection during Suspense resolution and prevents moving children when in pendingMounts state. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
|
Could you please add a test case? |
When a disabled Teleport inside Suspense has its mount deferred via pendingMounts, component children have vnode.component === null because mountChildren was never called. During Suspense.resolve(), move(pendingBranch) walks the tree and crashes on vnode.component.subTree for these unmounted components. Add a null check for vnode.component in the move function to skip components that have not been mounted yet. The deferred mount job will handle their placement after Suspense flushes its effects. close vuejs#14701
32c90bb to
aaa59da
Compare
Done — added a test case and also fixed the stale container reference in the deferred mount job. Please take a look. |
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: |
|
Thanks for the PR. |
|
/ecosystem-ci run |
Thanks for the refinement! Guarding at the moveTeleport entry is a more precise fix. Learned a lot from this PR. |
|
📝 Ran ecosystem CI: Open
|
close #14701
Problem
When a disabled
<Teleport>inside<Suspense>has its mount deferred viapendingMounts(introduced in #14642), component children havevnode.component === nullbecausemountChildrenwas never called. DuringSuspense.resolve(),move(pendingBranch)walks the vnode tree and crashes onvnode.component.subTreefor these unmounted components.Reproduction: https://play.vuejs.org/#eNp9UstuwjAQ/JWVewAklKhqTyggtYhDq75UOPoSkgUMiW3ZDlCh/HvXDgFatdw8O7Pr2ceBPWgdbStkA5bYzAjtwKKr9IhLUWplHLyqvCoQFkaV0IniBvqUDpdJ3OSQmoDDUhepQ49cMq2sRmkbRPhYJ25xq4abRVoU8zTbjF5Umgu5jKIoiX8Wiy+qXXCsz5zNlFyIZbS2SlIXBy4BOMtUqUWB5l07oaTlbACB8Rx9p3bPIeZMhf02nq0w2/wRX9u9j3H2YdCi2SJnJ86lZomuoSfTN9zT+0SWoeWr5CdaVVTeYyN7rGROti90we1T2AXNZmYne0eDaJvyRr2yDnrOaC/jK62f7d5F9yGPy5qmeN7q/4dwgBXUxzto1s8lzd468D/CkAQGZY5mAN0eDEew6nZyse30/CdcprtUOLi9fjSkH42VpA5p5x6E6AwLDBacGnI2V/kXZ5ALm84LzNt78htXkhJhICzJvCmSNfeWxG2NXwdUfwNztgbg
Trigger conditions (all required):
<Suspense>wrapping an async component (awaitin setup)<Teleport disabled>as a root siblingFix
Add a null check for
vnode.componentin themovefunction before accessing.subTree. Components with null instances are skipped — the deferred mount job handles their placement after Suspense flushes its effects.Summary by CodeRabbit
Tests
Bug Fixes