Skip to content

Commit 784d96c

Browse files
committed
fix(effectScope): should stop along with parent component
1 parent 0cada69 commit 784d96c

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

src/apis/effectScope.ts

+4
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,11 @@ export function recordEffectScope(
7575
scope = scope || activeEffectScope
7676
if (scope && scope.active) {
7777
scope.effects.push(effect)
78+
return
7879
}
80+
// destory on parent component unmounted
81+
const vm = getCurrentInstance()?.proxy
82+
vm && vm.$on('hook:destroyed', () => effect.stop())
7983
}
8084

8185
export function effectScope(detached?: boolean) {

test/v3/reactivity/effectScope.spec.ts

+31
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
computed,
99
ref,
1010
ComputedRef,
11+
createApp,
1112
} from '../../../src'
1213
import { mockWarn } from '../../helpers'
1314

@@ -251,4 +252,34 @@ describe('reactivity/effect/scope', () => {
251252
expect(watchSpy).toHaveBeenCalledTimes(1)
252253
expect(watchEffectSpy).toHaveBeenCalledTimes(2)
253254
})
255+
256+
it('should stop along with parent component', async () => {
257+
let dummy, doubled
258+
const counter = reactive({ num: 0 })
259+
260+
const root = document.createElement('div')
261+
const vm = createApp({
262+
setup() {
263+
const scope = new EffectScope()
264+
scope.run(() => {
265+
watchEffect(() => (dummy = counter.num))
266+
watchEffect(() => (doubled = counter.num * 2))
267+
})
268+
},
269+
})
270+
vm.mount(root)
271+
272+
expect(dummy).toBe(0)
273+
counter.num = 7
274+
await nextTick()
275+
expect(dummy).toBe(7)
276+
expect(doubled).toBe(14)
277+
278+
vm.unmount()
279+
280+
counter.num = 6
281+
await nextTick()
282+
expect(dummy).toBe(7)
283+
expect(doubled).toBe(14)
284+
})
254285
})

0 commit comments

Comments
 (0)