Skip to content

Commit

Permalink
fix(reactivity): shallowReactive map "unwraps" the nested refs (#8503)
Browse files Browse the repository at this point in the history
fix #8501
fix #11249
  • Loading branch information
liuseen-l authored Jul 16, 2024
1 parent 2d85441 commit 50ddafe
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 7 deletions.
23 changes: 23 additions & 0 deletions packages/reactivity/__tests__/reactive.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { isRef, ref } from '../src/ref'
import {
isProxy,
isReactive,
isReadonly,
isShallow,
markRaw,
reactive,
readonly,
Expand Down Expand Up @@ -359,4 +361,25 @@ describe('reactivity/reactive', () => {
const c = computed(() => {})
expect(isProxy(c)).toBe(false)
})

test('The results of the shallow and readonly assignments are the same (Map)', () => {
const map = reactive(new Map())
map.set('foo', shallowReactive({ a: 2 }))
expect(isShallow(map.get('foo'))).toBe(true)

map.set('bar', readonly({ b: 2 }))
expect(isReadonly(map.get('bar'))).toBe(true)
})

test('The results of the shallow and readonly assignments are the same (Set)', () => {
const set = reactive(new Set())
set.add(shallowReactive({ a: 2 }))
set.add(readonly({ b: 2 }))
let count = 0
for (const i of set) {
if (count === 0) expect(isShallow(i)).toBe(true)
else expect(isReadonly(i)).toBe(true)
count++
}
})
})
23 changes: 23 additions & 0 deletions packages/reactivity/__tests__/shallowReactive.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,29 @@ describe('shallowReactive', () => {
shallowSet.forEach(x => expect(isReactive(x)).toBe(false))
})

test('Setting a reactive object on a shallowReactive map', () => {
const msg = ref('ads')
const bar = reactive({ msg })
const foo = shallowReactive(new Map([['foo1', bar]]))
foo.set('foo2', bar)

expect(isReactive(foo.get('foo2'))).toBe(true)
expect(isReactive(foo.get('foo1'))).toBe(true)
})

test('Setting a reactive object on a shallowReactive set', () => {
const msg = ref(1)
const bar = reactive({ msg })
const foo = reactive({ msg })

const deps = shallowReactive(new Set([bar]))
deps.add(foo)

deps.forEach(dep => {
expect(isReactive(dep)).toBe(true)
})
})

// #1210
test('onTrack on called on objectSpread', () => {
const onTrackFn = vi.fn()
Expand Down
28 changes: 21 additions & 7 deletions packages/reactivity/src/collectionHandlers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { toRaw, toReactive, toReadonly } from './reactive'
import {
isReadonly,
isShallow,
toRaw,
toReactive,
toReadonly,
} from './reactive'
import {
ITERATE_KEY,
MAP_KEY_ITERATE_KEY,
Expand Down Expand Up @@ -72,8 +78,10 @@ function size(target: IterableCollections, isReadonly = false) {
return Reflect.get(target, 'size', target)
}

function add(this: SetTypes, value: unknown) {
value = toRaw(value)
function add(this: SetTypes, value: unknown, _isShallow = false) {
if (!_isShallow && !isShallow(value) && !isReadonly(value)) {
value = toRaw(value)
}
const target = toRaw(this)
const proto = getProto(target)
const hadKey = proto.has.call(target, value)
Expand All @@ -84,8 +92,10 @@ function add(this: SetTypes, value: unknown) {
return this
}

function set(this: MapTypes, key: unknown, value: unknown) {
value = toRaw(value)
function set(this: MapTypes, key: unknown, value: unknown, _isShallow = false) {
if (!_isShallow && !isShallow(value) && !isReadonly(value)) {
value = toRaw(value)
}
const target = toRaw(this)
const { has, get } = getProto(target)

Expand Down Expand Up @@ -263,8 +273,12 @@ function createInstrumentations() {
return size(this as unknown as IterableCollections)
},
has,
add,
set,
add(this: SetTypes, value: unknown) {
return add.call(this, value, true)
},
set(this: MapTypes, key: unknown, value: unknown) {
return set.call(this, key, value, true)
},
delete: deleteEntry,
clear,
forEach: createForEach(false, true),
Expand Down

0 comments on commit 50ddafe

Please sign in to comment.