]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(runtime-core): fix child component double update on props change
authorEvan You <yyx990803@gmail.com>
Tue, 17 Aug 2021 14:57:28 +0000 (10:57 -0400)
committerEvan You <yyx990803@gmail.com>
Tue, 17 Aug 2021 14:57:28 +0000 (10:57 -0400)
fix #4365

packages/runtime-core/__tests__/rendererComponent.spec.ts
packages/runtime-core/src/renderer.ts

index c389e1e835466b75b14bc3ad148136aeedee2dce..3fdc388823dd91ddc4b23b2a126310d40b4494a2 100644 (file)
@@ -324,4 +324,34 @@ describe('renderer: component', () => {
     expect(serializeInner(root)).toBe(``)
     expect(ids).toEqual([ids[0], ids[0] + 1, ids[0] + 2])
   })
+
+  test('child component props update should not lead to double update', async () => {
+    const text = ref(0)
+    const spy = jest.fn()
+
+    const App = {
+      render() {
+        return h(Comp, { text: text.value })
+      }
+    }
+
+    const Comp = {
+      props: ['text'],
+      render(this: any) {
+        spy()
+        return h('h1', this.text)
+      }
+    }
+
+    const root = nodeOps.createElement('div')
+    render(h(App), root)
+
+    expect(serializeInner(root)).toBe(`<h1>0</h1>`)
+    expect(spy).toHaveBeenCalledTimes(1)
+
+    text.value++
+    await nextTick()
+    expect(serializeInner(root)).toBe(`<h1>1</h1>`)
+    expect(spy).toHaveBeenCalledTimes(2)
+  })
 })
index 17eaaf44d5c63177a81bf569e4f336d310127c71..76848cb52f3b0f54d98e7c187fdc73dfb8ba514b 100644 (file)
@@ -1458,6 +1458,9 @@ function baseCreateRenderer(
           pushWarningContext(next || instance.vnode)
         }
 
+        // Disallow component effect recursion during pre-lifecycle hooks.
+        effect.allowRecurse = false
+
         if (next) {
           next.el = vnode.el
           updateComponentPreRender(instance, next, optimized)
@@ -1465,8 +1468,6 @@ function baseCreateRenderer(
           next = vnode
         }
 
-        // Disallow component effect recursion during pre-lifecycle hooks.
-        effect.allowRecurse = false
         // beforeUpdate hook
         if (bu) {
           invokeArrayFns(bu)
@@ -1481,6 +1482,7 @@ function baseCreateRenderer(
         ) {
           instance.emit('hook:beforeUpdate')
         }
+
         effect.allowRecurse = true
 
         // render