]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(reactivity): fix currentScope loss when running detached effect scope (#5575)
authorWei <a65162@gmail.com>
Tue, 12 Apr 2022 07:51:05 +0000 (15:51 +0800)
committerGitHub <noreply@github.com>
Tue, 12 Apr 2022 07:51:05 +0000 (03:51 -0400)
packages/reactivity/__tests__/effectScope.spec.ts
packages/reactivity/src/effectScope.ts

index 3ce8affe78cbfce375b9fd1a4532016b85bb2f78..6adda3d834ae822b5e938c7a473449d9a43a62a8 100644 (file)
@@ -6,7 +6,8 @@ import {
   onScopeDispose,
   computed,
   ref,
-  ComputedRef
+  ComputedRef,
+  getCurrentScope
 } from '../src'
 
 describe('reactivity/effect/scope', () => {
@@ -263,4 +264,17 @@ describe('reactivity/effect/scope', () => {
     expect(watchSpy).toHaveBeenCalledTimes(1)
     expect(watchEffectSpy).toHaveBeenCalledTimes(2)
   })
+
+  it('getCurrentScope() stays valid when running a detached nested EffectScope', () => {
+    const parentScope = new EffectScope()
+
+    parentScope.run(() => {
+      const currentScope = getCurrentScope()
+      expect(currentScope).toBeDefined()
+      const detachedScope = new EffectScope(true)
+      detachedScope.run(() => {})
+
+      expect(getCurrentScope()).toBe(currentScope)
+    })
+  })
 })
index fcacab6e381dd3e34dd328116932b1115ad9142e..01499c5a78e82763e5876f4d02908d27adbfdbfc 100644 (file)
@@ -8,7 +8,13 @@ export class EffectScope {
   effects: ReactiveEffect[] = []
   cleanups: (() => void)[] = []
 
+  /**
+   * only assinged by undetached scope
+   */
   parent: EffectScope | undefined
+  /**
+   * record undetached scopes
+   */
   scopes: EffectScope[] | undefined
   /**
    * track a child scope's index in its parent's scopes array for optimized
@@ -28,11 +34,12 @@ export class EffectScope {
 
   run<T>(fn: () => T): T | undefined {
     if (this.active) {
+      const currentEffectScope = activeEffectScope
       try {
         activeEffectScope = this
         return fn()
       } finally {
-        activeEffectScope = this.parent
+        activeEffectScope = currentEffectScope
       }
     } else if (__DEV__) {
       warn(`cannot run an inactive effect scope.`)