Skip to content

Commit 716275d

Browse files
authored
fix(reactivity): prevent endless recursion in computed getters (#11797)
1 parent c74176e commit 716275d

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

packages/reactivity/__tests__/computed.spec.ts

+45
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
import {
2+
type TestElement,
3+
defineComponent,
24
h,
35
nextTick,
46
nodeOps,
57
onMounted,
68
onUnmounted,
79
render,
810
serializeInner,
11+
triggerEvent,
912
} from '@vue/runtime-test'
1013
import {
1114
type DebuggerEvent,
@@ -958,4 +961,46 @@ describe('reactivity/computed', () => {
958961
newValue: 2,
959962
})
960963
})
964+
965+
test('should prevent endless recursion in self-referencing computed getters', async () => {
966+
const Comp = defineComponent({
967+
data() {
968+
return {
969+
counter: 0,
970+
}
971+
},
972+
973+
computed: {
974+
message(): string {
975+
if (this.counter === 0) {
976+
this.counter++
977+
return this.message
978+
} else {
979+
return `Step ${this.counter}`
980+
}
981+
},
982+
},
983+
984+
render() {
985+
return [
986+
h(
987+
'button',
988+
{
989+
onClick: () => {
990+
this.counter++
991+
},
992+
},
993+
'Step',
994+
),
995+
h('p', this.message),
996+
]
997+
},
998+
})
999+
const root = nodeOps.createElement('div')
1000+
render(h(Comp), root)
1001+
expect(serializeInner(root)).toBe(`<button>Step</button><p></p>`)
1002+
triggerEvent(root.children[1] as TestElement, 'click')
1003+
await nextTick()
1004+
expect(serializeInner(root)).toBe(`<button>Step</button><p>Step 2</p>`)
1005+
})
9611006
})

packages/reactivity/src/dep.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export class Dep {
4646
}
4747

4848
track(debugInfo?: DebuggerEventExtraInfo): Link | undefined {
49-
if (!activeSub || !shouldTrack) {
49+
if (!activeSub || !shouldTrack || activeSub === this.computed) {
5050
return
5151
}
5252

0 commit comments

Comments
 (0)