From 9956991f7a5f95a7da24cc39a94d3dda2c625bbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8A=B1=E6=9E=9C=E5=B1=B1=E5=A4=A7=E5=9C=A3?= <316783812@qq.com> Date: Mon, 26 Jun 2023 23:55:46 +0800 Subject: [PATCH] fix(reactivity): check rawValue exists in target via set.add #8647 --- packages/reactivity/__tests__/reactive.spec.ts | 12 ++++++++++++ packages/reactivity/src/collectionHandlers.ts | 11 +++++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/packages/reactivity/__tests__/reactive.spec.ts b/packages/reactivity/__tests__/reactive.spec.ts index 51c9ed42c8e..d13f441009c 100644 --- a/packages/reactivity/__tests__/reactive.spec.ts +++ b/packages/reactivity/__tests__/reactive.spec.ts @@ -99,6 +99,18 @@ describe('reactivity/reactive', () => { cset.delete(key) expect(dummy).toBe(false) }) + // #8647 + test('observing nest reactive in set', () => { + const observed = reactive({}) + const observedSet = reactive(new Set([observed])) + expect(observedSet.size).toBe(1) + + if (observedSet.has(observed)) { + // expect nothing happens + observedSet.add(observed) + } + expect(observedSet.size).toBe(1) + }) test('observed value should proxy mutations to original (Object)', () => { const original: any = { foo: 1 } diff --git a/packages/reactivity/src/collectionHandlers.ts b/packages/reactivity/src/collectionHandlers.ts index 381bbad6c28..73a4e30057a 100644 --- a/packages/reactivity/src/collectionHandlers.ts +++ b/packages/reactivity/src/collectionHandlers.ts @@ -67,13 +67,16 @@ function size(target: IterableCollections, isReadonly = false) { } function add(this: SetTypes, value: unknown) { - value = toRaw(value) + const rawValue = toRaw(value) const target = toRaw(this) const proto = getProto(target) - const hadKey = proto.has.call(target, value) + const hadKey = + value === rawValue + ? proto.has.call(target, rawValue) + : proto.has.call(target, rawValue) || proto.has.call(target, value) if (!hadKey) { - target.add(value) - trigger(target, TriggerOpTypes.ADD, value, value) + target.add(rawValue) + trigger(target, TriggerOpTypes.ADD, rawValue, rawValue) } return this }