]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix: Revert "fix(reactivity): avoid infinite loop when render access a side effect...
authorEvan You <evan@vuejs.org>
Fri, 28 Jun 2024 01:31:14 +0000 (09:31 +0800)
committerEvan You <evan@vuejs.org>
Fri, 28 Jun 2024 01:31:14 +0000 (09:31 +0800)
This reverts commit 8296e19855e369a7826f5ea26540a6da01dc7093.

packages/reactivity/__tests__/computed.spec.ts
packages/reactivity/src/computed.ts
packages/reactivity/src/constants.ts
packages/reactivity/src/effect.ts

index 0122f4e439181825064c2284b0ab6bc92fd4d3ff..10c09109fdbd8153efc2e6f1f9ad8fa417965d57 100644 (file)
@@ -456,78 +456,6 @@ describe('reactivity/computed', () => {
     expect(fnSpy).toBeCalledTimes(2)
   })
 
-  it('should mark dirty as MaybeDirty_ComputedSideEffect_Origin', () => {
-    const v = ref(1)
-    const c = computed(() => {
-      v.value += 1
-      return v.value
-    })
-
-    c.value
-    expect(c.effect._dirtyLevel).toBe(
-      DirtyLevels.MaybeDirty_ComputedSideEffect_Origin,
-    )
-    expect(COMPUTED_SIDE_EFFECT_WARN).toHaveBeenWarned()
-  })
-
-  it('should not infinite re-run effect when effect access original side effect computed', async () => {
-    const spy = vi.fn()
-    const v = ref(0)
-    const c = computed(() => {
-      v.value += 1
-      return v.value
-    })
-    const Comp = {
-      setup: () => {
-        return () => {
-          spy()
-          return v.value + c.value
-        }
-      },
-    }
-    const root = nodeOps.createElement('div')
-
-    render(h(Comp), root)
-    expect(spy).toBeCalledTimes(1)
-    await nextTick()
-    expect(c.effect._dirtyLevel).toBe(
-      DirtyLevels.MaybeDirty_ComputedSideEffect_Origin,
-    )
-    expect(serializeInner(root)).toBe('2')
-    expect(COMPUTED_SIDE_EFFECT_WARN).toHaveBeenWarned()
-  })
-
-  it('should not infinite re-run effect when effect access chained side effect computed', async () => {
-    const spy = vi.fn()
-    const v = ref(0)
-    const c1 = computed(() => {
-      v.value += 1
-      return v.value
-    })
-    const c2 = computed(() => v.value + c1.value)
-    const Comp = {
-      setup: () => {
-        return () => {
-          spy()
-          return v.value + c1.value + c2.value
-        }
-      },
-    }
-    const root = nodeOps.createElement('div')
-
-    render(h(Comp), root)
-    expect(spy).toBeCalledTimes(1)
-    await nextTick()
-    expect(c1.effect._dirtyLevel).toBe(
-      DirtyLevels.MaybeDirty_ComputedSideEffect_Origin,
-    )
-    expect(c2.effect._dirtyLevel).toBe(
-      DirtyLevels.MaybeDirty_ComputedSideEffect,
-    )
-    expect(serializeInner(root)).toBe('4')
-    expect(COMPUTED_SIDE_EFFECT_WARN).toHaveBeenWarned()
-  })
-
   it('should chained recurse effects clear dirty after trigger', () => {
     const v = ref(1)
     const c1 = computed(() => v.value)
@@ -554,9 +482,7 @@ describe('reactivity/computed', () => {
 
     c3.value
 
-    expect(c1.effect._dirtyLevel).toBe(
-      DirtyLevels.MaybeDirty_ComputedSideEffect_Origin,
-    )
+    expect(c1.effect._dirtyLevel).toBe(DirtyLevels.Dirty)
     expect(c2.effect._dirtyLevel).toBe(
       DirtyLevels.MaybeDirty_ComputedSideEffect,
     )
@@ -576,9 +502,7 @@ describe('reactivity/computed', () => {
     })
     const c2 = computed(() => v.value + c1.value)
     expect(c2.value).toBe('0foo')
-    expect(c2.effect._dirtyLevel).toBe(
-      DirtyLevels.MaybeDirty_ComputedSideEffect,
-    )
+    expect(c2.effect._dirtyLevel).toBe(DirtyLevels.Dirty)
     expect(c2.value).toBe('1foo')
     expect(COMPUTED_SIDE_EFFECT_WARN).toHaveBeenWarned()
   })
@@ -599,12 +523,8 @@ describe('reactivity/computed', () => {
       c2.value
     })
     expect(fnSpy).toBeCalledTimes(1)
-    expect(c1.effect._dirtyLevel).toBe(
-      DirtyLevels.MaybeDirty_ComputedSideEffect_Origin,
-    )
-    expect(c2.effect._dirtyLevel).toBe(
-      DirtyLevels.MaybeDirty_ComputedSideEffect,
-    )
+    expect(c1.effect._dirtyLevel).toBe(DirtyLevels.Dirty)
+    expect(c2.effect._dirtyLevel).toBe(DirtyLevels.Dirty)
     v.value = 2
     expect(fnSpy).toBeCalledTimes(2)
     expect(COMPUTED_SIDE_EFFECT_WARN).toHaveBeenWarned()
@@ -637,9 +557,7 @@ describe('reactivity/computed', () => {
     expect(c3.effect._dirtyLevel).toBe(DirtyLevels.MaybeDirty)
 
     c3.value
-    expect(c1.effect._dirtyLevel).toBe(
-      DirtyLevels.MaybeDirty_ComputedSideEffect_Origin,
-    )
+    expect(c1.effect._dirtyLevel).toBe(DirtyLevels.Dirty)
     expect(c2.effect._dirtyLevel).toBe(
       DirtyLevels.MaybeDirty_ComputedSideEffect,
     )
@@ -693,18 +611,11 @@ describe('reactivity/computed', () => {
 
     render(h(Comp), root)
     await nextTick()
-    expect(c.effect._dirtyLevel).toBe(
-      DirtyLevels.MaybeDirty_ComputedSideEffect_Origin,
-    )
     expect(serializeInner(root)).toBe('Hello World')
 
     v.value += ' World'
-    expect(c.effect._dirtyLevel).toBe(DirtyLevels.Dirty)
     await nextTick()
-    expect(c.effect._dirtyLevel).toBe(
-      DirtyLevels.MaybeDirty_ComputedSideEffect_Origin,
-    )
-    expect(serializeInner(root)).toBe('Hello World World World')
+    expect(serializeInner(root)).toBe('Hello World World World World')
     expect(COMPUTED_SIDE_EFFECT_WARN).toHaveBeenWarned()
   })
 
index 91eac36012f7afc7a09d716ed43a131c8dc925bc..da63fe84750af13db7bdb7c8d9968e65b8b9cbe0 100644 (file)
@@ -78,10 +78,7 @@ export class ComputedRefImpl<T> {
       triggerRefValue(self, DirtyLevels.Dirty)
     }
     trackRefValue(self)
-    if (
-      self.effect._dirtyLevel >=
-      DirtyLevels.MaybeDirty_ComputedSideEffect_Origin
-    ) {
+    if (self.effect._dirtyLevel >= DirtyLevels.MaybeDirty_ComputedSideEffect) {
       if (__DEV__ && (__TEST__ || this._warnRecursive)) {
         warn(COMPUTED_SIDE_EFFECT_WARN, `\n\ngetter: `, this.getter)
       }
index 4898d691703a3ec443cad1f6d199aae72acefe4b..baa75d61644c34ec76861948dab497a141ee243a 100644 (file)
@@ -23,10 +23,9 @@ export enum ReactiveFlags {
 }
 
 export enum DirtyLevels {
-  NotDirty,
-  QueryingDirty,
-  MaybeDirty_ComputedSideEffect_Origin,
-  MaybeDirty_ComputedSideEffect,
-  MaybeDirty,
-  Dirty,
+  NotDirty = 0,
+  QueryingDirty = 1,
+  MaybeDirty_ComputedSideEffect = 2,
+  MaybeDirty = 3,
+  Dirty = 4,
 }
index 40868545b4b390074f89c9cd7c7d1b3df3c79cdb..1528f4b1d89aa1ca7c8336c68de8d0670e73dff5 100644 (file)
@@ -76,9 +76,6 @@ export class ReactiveEffect<T = any> {
   }
 
   public get dirty() {
-    // treat original side effect computed as not dirty to avoid infinite loop
-    if (this._dirtyLevel === DirtyLevels.MaybeDirty_ComputedSideEffect_Origin)
-      return false
     if (
       this._dirtyLevel === DirtyLevels.MaybeDirty_ComputedSideEffect ||
       this._dirtyLevel === DirtyLevels.MaybeDirty
@@ -88,13 +85,6 @@ export class ReactiveEffect<T = any> {
       for (let i = 0; i < this._depsLength; i++) {
         const dep = this.deps[i]
         if (dep.computed) {
-          // treat chained side effect computed as dirty to force it re-run
-          // since we know the original side effect computed is dirty
-          if (
-            dep.computed.effect._dirtyLevel ===
-            DirtyLevels.MaybeDirty_ComputedSideEffect_Origin
-          )
-            return true
           triggerComputed(dep.computed)
           if (this._dirtyLevel >= DirtyLevels.Dirty) {
             break
@@ -308,30 +298,11 @@ export function triggerEffects(
   for (const effect of dep.keys()) {
     // dep.get(effect) is very expensive, we need to calculate it lazily and reuse the result
     let tracking: boolean | undefined
-
-    if (!dep.computed && effect.computed) {
-      if (
-        effect._runnings > 0 &&
-        (tracking ??= dep.get(effect) === effect._trackId)
-      ) {
-        effect._dirtyLevel = DirtyLevels.MaybeDirty_ComputedSideEffect_Origin
-        continue
-      }
-    }
-
     if (
       effect._dirtyLevel < dirtyLevel &&
       (tracking ??= dep.get(effect) === effect._trackId)
     ) {
       effect._shouldSchedule ||= effect._dirtyLevel === DirtyLevels.NotDirty
-      // always schedule if the computed is original side effect
-      // since we know it is actually dirty
-      if (
-        effect.computed &&
-        effect._dirtyLevel === DirtyLevels.MaybeDirty_ComputedSideEffect_Origin
-      ) {
-        effect._shouldSchedule = true
-      }
       effect._dirtyLevel = dirtyLevel
     }
     if (