Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
fix(observe): solve the Ref not unwrapping on the ssr side issue with…
… recursive way. (#723)

Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
  • Loading branch information
ygj6 and antfu committed Jul 2, 2021
1 parent df16c13 commit debd37d
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 5 deletions.
28 changes: 25 additions & 3 deletions src/reactivity/reactive.ts
Expand Up @@ -127,14 +127,32 @@ export function observe<T>(obj: T): T {

// in SSR, there is no __ob__. Mock for reactivity check
if (!hasOwn(observed, '__ob__')) {
def(observed, '__ob__', mockObserver(observed))
mockReactivityDeep(observed)
}

return observed
}

export function createObserver() {
return observe<any>({}).__ob__
/**
* Mock __ob__ for object recursively
*/
function mockReactivityDeep(obj: any, seen = new WeakMap<any, boolean>()) {
if (seen.has(obj)) return

def(obj, '__ob__', mockObserver(obj))
seen.set(obj, true)

for (const key of Object.keys(obj)) {
const value = obj[key]
if (
!(isPlainObject(value) || isArray(value)) ||
isRaw(value) ||
!Object.isExtensible(value)
) {
continue
}
mockReactivityDeep(value)
}
}

function mockObserver(value: any = {}): any {
Expand All @@ -149,6 +167,10 @@ function mockObserver(value: any = {}): any {
}
}

export function createObserver() {
return observe<any>({}).__ob__
}

export function shallowReactive<T extends object = any>(obj: T): T
export function shallowReactive(obj: any): any {
if (!isObject(obj)) {
Expand Down
3 changes: 1 addition & 2 deletions src/reactivity/set.ts
Expand Up @@ -41,8 +41,7 @@ export function set<T>(target: AnyObject, key: any, val: T): T {
return val
}
if (!ob) {
// If we are using `set` we can assume that the unwrapping is intended
defineAccessControl(target, key, val)
target[key] = val
return val
}
defineReactive(ob.value, key, val)
Expand Down
16 changes: 16 additions & 0 deletions test/ssr/ssrReactive.spec.ts
Expand Up @@ -102,4 +102,20 @@ describe('SSR Reactive', () => {
new: true,
})
})

// #721
it('should behave correctly for the nested ref in the object', () => {
const state = { old: ref(false) }
set(state, 'new', ref(true))
expect(JSON.stringify(state)).toBe(
'{"old":{"value":false},"new":{"value":true}}'
)
})

// #721
it('should behave correctly for ref of object', () => {
const state = ref({ old: ref(false) })
set(state.value, 'new', ref(true))
expect(JSON.stringify(state.value)).toBe('{"old":false,"new":true}')
})
})

0 comments on commit debd37d

Please sign in to comment.