Skip to content

Commit dffd270

Browse files
committed
Fix "effect should be removed from scope's effects after it is stopped"
1 parent 8dc97ef commit dffd270

File tree

1 file changed

+25
-1
lines changed

1 file changed

+25
-1
lines changed

packages/reactivity/src/watch.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,17 @@ import {
99
isPlainObject,
1010
isSet,
1111
} from '@vue/shared'
12+
import { Link } from 'alien-signals'
1213
import type { ComputedRef } from './computed'
1314
import { ReactiveFlags } from './constants'
1415
import {
1516
type DebuggerOptions,
1617
type EffectScheduler,
1718
ReactiveEffect,
1819
pauseTracking,
19-
resetTracking
20+
resetTracking,
2021
} from './effect'
22+
import { getCurrentScope } from './effectScope'
2123
import { isReactive, isShallow } from './reactive'
2224
import { type Ref, isRef } from './ref'
2325
import { warn } from './warning'
@@ -207,8 +209,30 @@ export function watch(
207209
getter = () => traverse(baseGetter(), depth)
208210
}
209211

212+
const scope = getCurrentScope()
210213
const watchHandle: WatchHandle = () => {
211214
effect.stop()
215+
if (scope) {
216+
let prevDep: Link | undefined
217+
let link = scope.deps
218+
while (link !== undefined) {
219+
if (link.dep === effect) {
220+
const nextDep = link.nextDep
221+
if (prevDep !== undefined) {
222+
prevDep.nextDep = nextDep
223+
}
224+
if (nextDep === undefined) {
225+
scope.depsTail = prevDep
226+
}
227+
if (prevDep === undefined) {
228+
scope.deps = nextDep
229+
}
230+
Link.release(link)
231+
break
232+
}
233+
link = link.nextDep
234+
}
235+
}
212236
}
213237

214238
if (once && cb) {

0 commit comments

Comments
 (0)