Просмотр исходного кода

fix(Suspense): fix edge case of Suspense being patched during async HOC child remount

Evan You 2 лет назад
Родитель
Сommit
f0f6f7cea6

+ 40 - 0
packages/runtime-core/__tests__/components/Suspense.spec.ts

@@ -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(

+ 1 - 0
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) {