Explorar o código

fix(reactivity): fix tracking for readonly + reactive Map (#3604)

fix #3602
HcySunYang %!s(int64=5) %!d(string=hai) anos
pai
achega
5036c51cb7

+ 30 - 1
packages/reactivity/__tests__/effect.spec.ts

@@ -7,7 +7,8 @@ import {
   TriggerOpTypes,
   DebuggerEvent,
   markRaw,
-  shallowReactive
+  shallowReactive,
+  readonly
 } from '../src/index'
 import { ITERATE_KEY } from '../src/effect'
 
@@ -832,4 +833,32 @@ describe('reactivity/effect', () => {
     observed2.obj2 = obj2
     expect(fnSpy2).toHaveBeenCalledTimes(1)
   })
+
+  describe('readonly + reactive for Map', () => {
+    test('should work with readonly(reactive(Map))', () => {
+      const m = reactive(new Map())
+      const roM = readonly(m)
+      const fnSpy = jest.fn(() => roM.get(1))
+
+      effect(fnSpy)
+      expect(fnSpy).toHaveBeenCalledTimes(1)
+      m.set(1, 1)
+      expect(fnSpy).toHaveBeenCalledTimes(2)
+    })
+
+    test('should work with observed value as key', () => {
+      const key = reactive({})
+      const m = reactive(new Map())
+      m.set(key, 1)
+      const roM = readonly(m)
+      const fnSpy = jest.fn(() => roM.get(key))
+
+      effect(fnSpy)
+      expect(fnSpy).toHaveBeenCalledTimes(1)
+      m.set(key, 1)
+      expect(fnSpy).toHaveBeenCalledTimes(1)
+      m.set(key, 2)
+      expect(fnSpy).toHaveBeenCalledTimes(2)
+    })
+  })
 })

+ 4 - 0
packages/reactivity/src/collectionHandlers.ts

@@ -49,6 +49,10 @@ function get(
     return wrap(target.get(key))
   } else if (has.call(rawTarget, rawKey)) {
     return wrap(target.get(rawKey))
+  } else if (target !== rawTarget) {
+    // #3602 readonly(reactive(Map))
+    // ensure that the nested reactive `Map` can do tracking for itself
+    target.get(key)
   }
 }