Skip to content

Commit 2193284

Browse files
committedNov 14, 2024··
fix(reactiivty): avoid unnecessary watcher effect removal from inactive scope
close #5783 close #5806
1 parent e9f3e6b commit 2193284

File tree

3 files changed

+39
-2
lines changed

3 files changed

+39
-2
lines changed
 

‎packages/reactivity/__tests__/effectScope.spec.ts

+37
Original file line numberDiff line numberDiff line change
@@ -322,4 +322,41 @@ describe('reactivity/effect/scope', () => {
322322
scope.resume()
323323
expect(fnSpy).toHaveBeenCalledTimes(3)
324324
})
325+
326+
test('removing a watcher while stopping its effectScope', async () => {
327+
const count = ref(0)
328+
const scope = effectScope()
329+
let watcherCalls = 0
330+
let cleanupCalls = 0
331+
332+
scope.run(() => {
333+
const stop1 = watch(count, () => {
334+
watcherCalls++
335+
})
336+
watch(count, (val, old, onCleanup) => {
337+
watcherCalls++
338+
onCleanup(() => {
339+
cleanupCalls++
340+
stop1()
341+
})
342+
})
343+
watch(count, () => {
344+
watcherCalls++
345+
})
346+
})
347+
348+
expect(watcherCalls).toBe(0)
349+
expect(cleanupCalls).toBe(0)
350+
351+
count.value++
352+
await nextTick()
353+
expect(watcherCalls).toBe(3)
354+
expect(cleanupCalls).toBe(0)
355+
356+
scope.stop()
357+
count.value++
358+
await nextTick()
359+
expect(watcherCalls).toBe(3)
360+
expect(cleanupCalls).toBe(1)
361+
})
325362
})

‎packages/reactivity/src/effectScope.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ export class EffectScope {
117117

118118
stop(fromParent?: boolean): void {
119119
if (this._active) {
120+
this._active = false
120121
let i, l
121122
for (i = 0, l = this.effects.length; i < l; i++) {
122123
this.effects[i].stop()
@@ -139,7 +140,6 @@ export class EffectScope {
139140
}
140141
}
141142
this.parent = undefined
142-
this._active = false
143143
}
144144
}
145145
}

‎packages/reactivity/src/watch.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ export function watch(
213213
const scope = getCurrentScope()
214214
const watchHandle: WatchHandle = () => {
215215
effect.stop()
216-
if (scope) {
216+
if (scope && scope.active) {
217217
remove(scope.effects, effect)
218218
}
219219
}

0 commit comments

Comments
 (0)
Please sign in to comment.