fix(runtime-core): fix child component double update on props change

fix #4365
This commit is contained in:
Evan You 2021-08-17 10:57:28 -04:00
parent 57f10812cc
commit c1f564e1dc
2 changed files with 34 additions and 2 deletions

View File

@ -324,4 +324,34 @@ describe('renderer: component', () => {
expect(serializeInner(root)).toBe(``) expect(serializeInner(root)).toBe(``)
expect(ids).toEqual([ids[0], ids[0] + 1, ids[0] + 2]) 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)
})
}) })

View File

@ -1458,6 +1458,9 @@ function baseCreateRenderer(
pushWarningContext(next || instance.vnode) pushWarningContext(next || instance.vnode)
} }
// Disallow component effect recursion during pre-lifecycle hooks.
effect.allowRecurse = false
if (next) { if (next) {
next.el = vnode.el next.el = vnode.el
updateComponentPreRender(instance, next, optimized) updateComponentPreRender(instance, next, optimized)
@ -1465,8 +1468,6 @@ function baseCreateRenderer(
next = vnode next = vnode
} }
// Disallow component effect recursion during pre-lifecycle hooks.
effect.allowRecurse = false
// beforeUpdate hook // beforeUpdate hook
if (bu) { if (bu) {
invokeArrayFns(bu) invokeArrayFns(bu)
@ -1481,6 +1482,7 @@ function baseCreateRenderer(
) { ) {
instance.emit('hook:beforeUpdate') instance.emit('hook:beforeUpdate')
} }
effect.allowRecurse = true effect.allowRecurse = true
// render // render