diff --git a/packages/reactivity/__tests__/effect.spec.ts b/packages/reactivity/__tests__/effect.spec.ts index 34a0976030a..589c69195bf 100644 --- a/packages/reactivity/__tests__/effect.spec.ts +++ b/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) + }) + }) }) diff --git a/packages/reactivity/src/collectionHandlers.ts b/packages/reactivity/src/collectionHandlers.ts index 4eb57bf6c67..a0ca8d080d4 100644 --- a/packages/reactivity/src/collectionHandlers.ts +++ b/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) } }