Skip to content

Commit 50ddafe

Browse files
authored
fix(reactivity): shallowReactive map "unwraps" the nested refs (#8503)
fix #8501 fix #11249
1 parent 2d85441 commit 50ddafe

File tree

3 files changed

+67
-7
lines changed

3 files changed

+67
-7
lines changed

packages/reactivity/__tests__/reactive.spec.ts

+23
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import { isRef, ref } from '../src/ref'
22
import {
33
isProxy,
44
isReactive,
5+
isReadonly,
6+
isShallow,
57
markRaw,
68
reactive,
79
readonly,
@@ -359,4 +361,25 @@ describe('reactivity/reactive', () => {
359361
const c = computed(() => {})
360362
expect(isProxy(c)).toBe(false)
361363
})
364+
365+
test('The results of the shallow and readonly assignments are the same (Map)', () => {
366+
const map = reactive(new Map())
367+
map.set('foo', shallowReactive({ a: 2 }))
368+
expect(isShallow(map.get('foo'))).toBe(true)
369+
370+
map.set('bar', readonly({ b: 2 }))
371+
expect(isReadonly(map.get('bar'))).toBe(true)
372+
})
373+
374+
test('The results of the shallow and readonly assignments are the same (Set)', () => {
375+
const set = reactive(new Set())
376+
set.add(shallowReactive({ a: 2 }))
377+
set.add(readonly({ b: 2 }))
378+
let count = 0
379+
for (const i of set) {
380+
if (count === 0) expect(isShallow(i)).toBe(true)
381+
else expect(isReadonly(i)).toBe(true)
382+
count++
383+
}
384+
})
362385
})

packages/reactivity/__tests__/shallowReactive.spec.ts

+23
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,29 @@ describe('shallowReactive', () => {
123123
shallowSet.forEach(x => expect(isReactive(x)).toBe(false))
124124
})
125125

126+
test('Setting a reactive object on a shallowReactive map', () => {
127+
const msg = ref('ads')
128+
const bar = reactive({ msg })
129+
const foo = shallowReactive(new Map([['foo1', bar]]))
130+
foo.set('foo2', bar)
131+
132+
expect(isReactive(foo.get('foo2'))).toBe(true)
133+
expect(isReactive(foo.get('foo1'))).toBe(true)
134+
})
135+
136+
test('Setting a reactive object on a shallowReactive set', () => {
137+
const msg = ref(1)
138+
const bar = reactive({ msg })
139+
const foo = reactive({ msg })
140+
141+
const deps = shallowReactive(new Set([bar]))
142+
deps.add(foo)
143+
144+
deps.forEach(dep => {
145+
expect(isReactive(dep)).toBe(true)
146+
})
147+
})
148+
126149
// #1210
127150
test('onTrack on called on objectSpread', () => {
128151
const onTrackFn = vi.fn()

packages/reactivity/src/collectionHandlers.ts

+21-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import { toRaw, toReactive, toReadonly } from './reactive'
1+
import {
2+
isReadonly,
3+
isShallow,
4+
toRaw,
5+
toReactive,
6+
toReadonly,
7+
} from './reactive'
28
import {
39
ITERATE_KEY,
410
MAP_KEY_ITERATE_KEY,
@@ -72,8 +78,10 @@ function size(target: IterableCollections, isReadonly = false) {
7278
return Reflect.get(target, 'size', target)
7379
}
7480

75-
function add(this: SetTypes, value: unknown) {
76-
value = toRaw(value)
81+
function add(this: SetTypes, value: unknown, _isShallow = false) {
82+
if (!_isShallow && !isShallow(value) && !isReadonly(value)) {
83+
value = toRaw(value)
84+
}
7785
const target = toRaw(this)
7886
const proto = getProto(target)
7987
const hadKey = proto.has.call(target, value)
@@ -84,8 +92,10 @@ function add(this: SetTypes, value: unknown) {
8492
return this
8593
}
8694

87-
function set(this: MapTypes, key: unknown, value: unknown) {
88-
value = toRaw(value)
95+
function set(this: MapTypes, key: unknown, value: unknown, _isShallow = false) {
96+
if (!_isShallow && !isShallow(value) && !isReadonly(value)) {
97+
value = toRaw(value)
98+
}
8999
const target = toRaw(this)
90100
const { has, get } = getProto(target)
91101

@@ -263,8 +273,12 @@ function createInstrumentations() {
263273
return size(this as unknown as IterableCollections)
264274
},
265275
has,
266-
add,
267-
set,
276+
add(this: SetTypes, value: unknown) {
277+
return add.call(this, value, true)
278+
},
279+
set(this: MapTypes, key: unknown, value: unknown) {
280+
return set.call(this, key, value, true)
281+
},
268282
delete: deleteEntry,
269283
clear,
270284
forEach: createForEach(false, true),

0 commit comments

Comments
 (0)