import {
+ ref,
reactive,
effect,
stop,
expect(dummy).toBe(3)
})
+ // #5707
+ // when an effect completes its run, it should clear the tracking bits of
+ // its tracked deps. However, if the effect stops itself, the deps list is
+ // emptied so their bits are never cleared.
+ it('edge case: self-stopping effect tracking ref', () => {
+ const c = ref(true)
+ const runner = effect(() => {
+ // reference ref
+ if (!c.value) {
+ // stop itself while running
+ stop(runner)
+ }
+ })
+ // trigger run
+ c.value = !c.value
+ // should clear bits
+ expect((c as any).dep.w).toBe(0)
+ expect((c as any).dep.n).toBe(0)
+ })
+
it('events: onStop', () => {
const onStop = jest.fn()
const runner = effect(() => {}, {
* @internal
*/
allowRecurse?: boolean
+ /**
+ * @internal
+ */
+ private deferStop?: boolean
onStop?: () => void
// dev only
activeEffect = this.parent
shouldTrack = lastShouldTrack
this.parent = undefined
+
+ if (this.deferStop) {
+ this.stop()
+ }
}
}
stop() {
- if (this.active) {
+ // stopped while running itself - defer the cleanup
+ if (activeEffect === this) {
+ this.deferStop = true
+ } else if (this.active) {
cleanupEffect(this)
if (this.onStop) {
this.onStop()