Sfoglia il codice sorgente

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

Evan You 3 anni fa
parent
commit
a71f9ac41a

+ 11 - 0
packages/reactivity/__tests__/effectScope.spec.ts

@@ -277,4 +277,15 @@ describe('reactivity/effect/scope', () => {
       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)
+    })
+  })
 })

+ 4 - 3
packages/reactivity/src/effectScope.ts

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