fix(effectScope): calling off() of a detached scope should not break currentScope

This commit is contained in:
Evan You 2022-10-14 10:53:23 +08:00
parent 35dc2bbe7d
commit a71f9ac41a
2 changed files with 15 additions and 3 deletions

View File

@ -277,4 +277,15 @@ describe('reactivity/effect/scope', () => {
expect(getCurrentScope()).toBe(currentScope) expect(getCurrentScope()).toBe(currentScope)
}) })
}) })
it('calling .off() of a detached scope inside an active scope should not break currentScope', () => {
const parentScope = new EffectScope()
parentScope.run(() => {
const childScope = new EffectScope(true)
childScope.on()
childScope.off()
expect(getCurrentScope()).toBe(parentScope)
})
})
}) })

View File

@ -34,9 +34,9 @@ export class EffectScope {
*/ */
private index: number | undefined private index: number | undefined
constructor(detached = false) { constructor(public detached = false) {
if (!detached && activeEffectScope) {
this.parent = activeEffectScope this.parent = activeEffectScope
if (!detached && activeEffectScope) {
this.index = this.index =
(activeEffectScope.scopes || (activeEffectScope.scopes = [])).push( (activeEffectScope.scopes || (activeEffectScope.scopes = [])).push(
this this
@ -89,7 +89,7 @@ export class EffectScope {
} }
} }
// nested scope, dereference from parent to avoid memory leaks // nested scope, dereference from parent to avoid memory leaks
if (this.parent && !fromParent) { if (!this.detached && this.parent && !fromParent) {
// optimized O(1) removal // optimized O(1) removal
const last = this.parent.scopes!.pop() const last = this.parent.scopes!.pop()
if (last && last !== this) { if (last && last !== this) {
@ -97,6 +97,7 @@ export class EffectScope {
last.index = this.index! last.index = this.index!
} }
} }
this.parent = undefined
this.active = false this.active = false
} }
} }