parent
f4f5e80a19
commit
154233abdb
@ -1,4 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
|
ref,
|
||||||
reactive,
|
reactive,
|
||||||
effect,
|
effect,
|
||||||
stop,
|
stop,
|
||||||
@ -801,6 +802,26 @@ describe('reactivity/effect', () => {
|
|||||||
expect(dummy).toBe(3)
|
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', () => {
|
it('events: onStop', () => {
|
||||||
const onStop = jest.fn()
|
const onStop = jest.fn()
|
||||||
const runner = effect(() => {}, {
|
const runner = effect(() => {}, {
|
||||||
|
@ -64,6 +64,10 @@ export class ReactiveEffect<T = any> {
|
|||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
allowRecurse?: boolean
|
allowRecurse?: boolean
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
private deferStop?: boolean
|
||||||
|
|
||||||
onStop?: () => void
|
onStop?: () => void
|
||||||
// dev only
|
// dev only
|
||||||
@ -114,11 +118,18 @@ export class ReactiveEffect<T = any> {
|
|||||||
activeEffect = this.parent
|
activeEffect = this.parent
|
||||||
shouldTrack = lastShouldTrack
|
shouldTrack = lastShouldTrack
|
||||||
this.parent = undefined
|
this.parent = undefined
|
||||||
|
|
||||||
|
if (this.deferStop) {
|
||||||
|
this.stop()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stop() {
|
stop() {
|
||||||
if (this.active) {
|
// stopped while running itself - defer the cleanup
|
||||||
|
if (activeEffect === this) {
|
||||||
|
this.deferStop = true
|
||||||
|
} else if (this.active) {
|
||||||
cleanupEffect(this)
|
cleanupEffect(this)
|
||||||
if (this.onStop) {
|
if (this.onStop) {
|
||||||
this.onStop()
|
this.onStop()
|
||||||
|
Loading…
Reference in New Issue
Block a user