From: Evan You Date: Fri, 15 Dec 2023 03:39:50 +0000 (+0800) Subject: fix(Suspense): fix edge case of Suspense being patched during async HOC child remount X-Git-Tag: v3.4.0-beta.3~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f0f6f7cea6e16650181e71dcfccbee405a1db503;p=thirdparty%2Fvuejs%2Fcore.git fix(Suspense): fix edge case of Suspense being patched during async HOC child remount --- diff --git a/packages/runtime-core/__tests__/components/Suspense.spec.ts b/packages/runtime-core/__tests__/components/Suspense.spec.ts index 92638cc6ba..c986ffdd79 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 38a9e8d19d..2be51a2274 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) {