浏览代码

fix(reactivity): do not remove dep from depsMap when unsubbed by computed

follow up of 235ea4772 after discovering regression in vant ecosystem-ci tests
Evan You 1 年之前
父节点
当前提交
960706eebf
共有 2 个文件被更改,包括 22 次插入4 次删除
  1. 19 1
      packages/reactivity/__tests__/computed.spec.ts
  2. 3 3
      packages/reactivity/src/effect.ts

+ 19 - 1
packages/reactivity/__tests__/computed.spec.ts

@@ -1006,9 +1006,27 @@ describe('reactivity/computed', () => {
     expect(serializeInner(root)).toBe(`<button>Step</button><p>Step 2</p>`)
   })
 
-  it('manual trigger computed', () => {
+  test('manual trigger computed', () => {
     const cValue = computed(() => 1)
     triggerRef(cValue)
     expect(cValue.value).toBe(1)
   })
+
+  test('computed should remain live after losing all subscribers', () => {
+    const toggle = ref(true)
+    const state = reactive({
+      a: 1,
+    })
+    const p = computed(() => state.a + 1)
+    const pp = computed(() => {
+      return toggle.value ? p.value : 111
+    })
+
+    const { effect: e } = effect(() => pp.value)
+    e.stop()
+
+    expect(p.value).toBe(2)
+    state.a++
+    expect(p.value).toBe(3)
+  })
 })

+ 3 - 3
packages/reactivity/src/effect.ts

@@ -399,7 +399,7 @@ export function refreshComputed(computed: ComputedRefImpl): undefined {
   }
 }
 
-function removeSub(link: Link) {
+function removeSub(link: Link, fromComputed = false) {
   const { dep, prevSub, nextSub } = link
   if (prevSub) {
     prevSub.nextSub = nextSub
@@ -425,9 +425,9 @@ function removeSub(link: Link) {
       // value can be GCed
       dep.computed.flags &= ~EffectFlags.TRACKING
       for (let l = dep.computed.deps; l; l = l.nextDep) {
-        removeSub(l)
+        removeSub(l, true)
       }
-    } else if (dep.map) {
+    } else if (dep.map && !fromComputed) {
       // property dep, remove it from the owner depsMap
       dep.map.delete(dep.key)
       if (!dep.map.size) targetMap.delete(dep.target!)