From: Evan You Date: Tue, 17 Aug 2021 14:57:28 +0000 (-0400) Subject: fix(runtime-core): fix child component double update on props change X-Git-Tag: v3.2.4~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c1f564e1dc40eda9af657c30cd787a8d770dde0f;p=thirdparty%2Fvuejs%2Fcore.git fix(runtime-core): fix child component double update on props change fix #4365 --- diff --git a/packages/runtime-core/__tests__/rendererComponent.spec.ts b/packages/runtime-core/__tests__/rendererComponent.spec.ts index c389e1e835..3fdc388823 100644 --- a/packages/runtime-core/__tests__/rendererComponent.spec.ts +++ b/packages/runtime-core/__tests__/rendererComponent.spec.ts @@ -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(`

0

`) + expect(spy).toHaveBeenCalledTimes(1) + + text.value++ + await nextTick() + expect(serializeInner(root)).toBe(`

1

`) + expect(spy).toHaveBeenCalledTimes(2) + }) }) diff --git a/packages/runtime-core/src/renderer.ts b/packages/runtime-core/src/renderer.ts index 17eaaf44d5..76848cb52f 100644 --- a/packages/runtime-core/src/renderer.ts +++ b/packages/runtime-core/src/renderer.ts @@ -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