]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(Suspense): fix edge case of Suspense being patched during async HOC child remount
authorEvan You <yyx990803@gmail.com>
Fri, 15 Dec 2023 03:39:50 +0000 (11:39 +0800)
committerEvan You <yyx990803@gmail.com>
Fri, 15 Dec 2023 03:39:50 +0000 (11:39 +0800)
packages/runtime-core/__tests__/components/Suspense.spec.ts
packages/runtime-core/src/componentRenderUtils.ts

index 92638cc6ba3a4b37b3c0e97e2554dfbd96d76a17..c986ffdd796a706e56e30607af1adb78ab9e144a 100644 (file)
@@ -1690,6 +1690,46 @@ describe('Suspense', () => {
     expect(serializeInner(root)).toBe(`<div>sync</div>`)
   })
 
+  // #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(
index 38a9e8d19d801c8c18205ff6b6d7c7e1f9d0aaf2..2be51a227438f88df45f3b14e99ddde94c899f86 100644 (file)
@@ -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) {