expect(dummy).toBe(7)
})
+ it('should derefence child scope from parent scope after stopping child scope (no memleaks)', async () => {
+ const parent = new EffectScope()
+ const child = parent.run(() => new EffectScope())!
+ expect(parent.effects.includes(child)).toBe(true)
+ child.stop()
+ expect(parent.effects.includes(child)).toBe(false)
+ })
+
it('test with higher level APIs', async () => {
const r = ref(1)
+import { remove } from '@vue/shared'
import { ReactiveEffect } from './effect'
import { warn } from './warning'
active = true
effects: (ReactiveEffect | EffectScope)[] = []
cleanups: (() => void)[] = []
+ parent: EffectScope | undefined
constructor(detached = false) {
if (!detached) {
recordEffectScope(this)
+ this.parent = activeEffectScope
}
}
}
}
- stop() {
+ stop(fromParent = false) {
if (this.active) {
- this.effects.forEach(e => e.stop())
+ this.effects.forEach(e => e.stop(true))
this.cleanups.forEach(cleanup => cleanup())
this.active = false
+ if (!fromParent && this.parent) {
+ remove(this.parent.effects, this)
+ }
}
}
}