Skip to content

Commit 5dc27ca

Browse files
authored
fix(reactivity): handle Set with initial reactive values edge case (#12393)
fix #8647
1 parent bbb8977 commit 5dc27ca

2 files changed

Lines changed: 22 additions & 6 deletions

File tree

packages/reactivity/__tests__/reactive.spec.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,19 @@ describe('reactivity/reactive', () => {
112112
expect(dummy).toBe(false)
113113
})
114114

115+
// #8647
116+
test('observing Set with reactive initial value', () => {
117+
const observed = reactive({})
118+
const observedSet = reactive(new Set([observed]))
119+
120+
expect(observedSet.has(observed)).toBe(true)
121+
expect(observedSet.size).toBe(1)
122+
123+
// expect nothing happens
124+
observedSet.add(observed)
125+
expect(observedSet.size).toBe(1)
126+
})
127+
115128
test('observed value should proxy mutations to original (Object)', () => {
116129
const original: any = { foo: 1 }
117130
const observed = reactive(original)

packages/reactivity/src/collectionHandlers.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -167,15 +167,18 @@ function createInstrumentations(
167167
}
168168
: {
169169
add(this: SetTypes, value: unknown) {
170-
if (!shallow && !isShallow(value) && !isReadonly(value)) {
171-
value = toRaw(value)
172-
}
173170
const target = toRaw(this)
174171
const proto = getProto(target)
175-
const hadKey = proto.has.call(target, value)
172+
const valueToAdd =
173+
!shallow && !isShallow(value) && !isReadonly(value)
174+
? toRaw(value)
175+
: value
176+
const hadKey =
177+
proto.has.call(target, valueToAdd) ||
178+
(value !== valueToAdd && proto.has.call(target, value))
176179
if (!hadKey) {
177-
target.add(value)
178-
trigger(target, TriggerOpTypes.ADD, value, value)
180+
target.add(valueToAdd)
181+
trigger(target, TriggerOpTypes.ADD, valueToAdd, valueToAdd)
179182
}
180183
return this
181184
},

0 commit comments

Comments
 (0)