diff --git a/packages/runtime-core/__tests__/components/Suspense.spec.ts b/packages/runtime-core/__tests__/components/Suspense.spec.ts index 92638cc6ba3..c986ffdd796 100644 --- a/packages/runtime-core/__tests__/components/Suspense.spec.ts +++ b/packages/runtime-core/__tests__/components/Suspense.spec.ts @@ -1690,6 +1690,46 @@ describe('Suspense', () => { expect(serializeInner(root)).toBe(`
sync
`) }) + // #6416 follow up + test('Suspense patched during HOC async component re-mount', async () => { + const key = ref('k') + const data = ref('data') + + const Async = defineAsyncComponent({ + render() { + return h('div', 'async') + } + }) + + const Comp = { + render() { + return h(Async, { key: key.value }) + } + } + + const root = nodeOps.createElement('div') + const App = { + render() { + return h(Suspense, null, { + default: h(Comp, { data: data.value }) + }) + } + } + render(h(App), root) + expect(serializeInner(root)).toBe(``) + + await Promise.all(deps) + + // async mounted, but key change causing a new async comp to be loaded + key.value = 'k1' + await nextTick() + + // patch the Suspense + // should not throw error due to Suspense vnode.el being null + data.value = 'data2' + await Promise.all(deps) + }) + describe('warnings', () => { // base function to check if a combination of slots warns or not function baseCheckWarn( diff --git a/packages/runtime-core/src/componentRenderUtils.ts b/packages/runtime-core/src/componentRenderUtils.ts index 38a9e8d19d8..2be51a22743 100644 --- a/packages/runtime-core/src/componentRenderUtils.ts +++ b/packages/runtime-core/src/componentRenderUtils.ts @@ -428,6 +428,7 @@ export function updateHOCHostEl( { vnode, parent }: ComponentInternalInstance, el: typeof vnode.el // HostNode ) { + if (!el) return while (parent) { const root = parent.subTree if (root.suspense && root.suspense.activeBranch === vnode) {