Parcourir la source

fix(Suspence): handle Suspense + KeepAlive HMR updating edge case (#13076)

close #13075
yangxiuxiu il y a 7 mois
Parent
commit
5d75a170c8

+ 52 - 0
packages/runtime-core/__tests__/hmr.spec.ts

@@ -895,6 +895,58 @@ describe('hot module replacement', () => {
     expect(serializeInner(root)).toBe('<div>bar</div>')
   })
 
+  test('multi reload child wrapped in Suspense + KeepAlive', async () => {
+    const id = 'test-child-reload-3'
+    const Child: ComponentOptions = {
+      __hmrId: id,
+      setup() {
+        const count = ref(0)
+        return { count }
+      },
+      render: compileToFunction(`<div>{{ count }}</div>`),
+    }
+    createRecord(id, Child)
+
+    const appId = 'test-app-id'
+    const App: ComponentOptions = {
+      __hmrId: appId,
+      components: { Child },
+      render: compileToFunction(`
+        <KeepAlive>
+          <Suspense>
+            <Child />
+          </Suspense>
+        </KeepAlive>
+      `),
+    }
+
+    const root = nodeOps.createElement('div')
+    render(h(App), root)
+    expect(serializeInner(root)).toBe('<div>0</div>')
+    await timeout()
+    reload(id, {
+      __hmrId: id,
+      setup() {
+        const count = ref(1)
+        return { count }
+      },
+      render: compileToFunction(`<div>{{ count }}</div>`),
+    })
+    await timeout()
+    expect(serializeInner(root)).toBe('<div>1</div>')
+
+    reload(id, {
+      __hmrId: id,
+      setup() {
+        const count = ref(2)
+        return { count }
+      },
+      render: compileToFunction(`<div>{{ count }}</div>`),
+    })
+    await timeout()
+    expect(serializeInner(root)).toBe('<div>2</div>')
+  })
+
   test('rerender for nested component', () => {
     const id = 'child-nested-rerender'
     const Foo: ComponentOptions = {

+ 1 - 1
packages/runtime-core/src/components/BaseTransition.ts

@@ -204,7 +204,7 @@ const BaseTransitionImpl: ComponentOptions = {
       if (
         oldInnerChild &&
         oldInnerChild.type !== Comment &&
-        !isSameVNodeType(innerChild, oldInnerChild) &&
+        !isSameVNodeType(oldInnerChild, innerChild) &&
         recursiveGetSubtree(instance).type !== Comment
       ) {
         let leavingHooks = resolveTransitionHooks(

+ 3 - 3
packages/runtime-core/src/components/Suspense.ts

@@ -235,7 +235,7 @@ function patchSuspense(
   const { activeBranch, pendingBranch, isInFallback, isHydrating } = suspense
   if (pendingBranch) {
     suspense.pendingBranch = newBranch
-    if (isSameVNodeType(newBranch, pendingBranch)) {
+    if (isSameVNodeType(pendingBranch, newBranch)) {
       // same root type but content may have changed.
       patch(
         pendingBranch,
@@ -321,7 +321,7 @@ function patchSuspense(
           )
           setActiveBranch(suspense, newFallback)
         }
-      } else if (activeBranch && isSameVNodeType(newBranch, activeBranch)) {
+      } else if (activeBranch && isSameVNodeType(activeBranch, newBranch)) {
         // toggled "back" to current active branch
         patch(
           activeBranch,
@@ -355,7 +355,7 @@ function patchSuspense(
       }
     }
   } else {
-    if (activeBranch && isSameVNodeType(newBranch, activeBranch)) {
+    if (activeBranch && isSameVNodeType(activeBranch, newBranch)) {
       // root did not change, just normal patch
       patch(
         activeBranch,