Skip to content

Commit

Permalink
feat(reactivity): store value cache on CustomRefs impls (#11539)
Browse files Browse the repository at this point in the history
Co-authored-by: Evan You <evan@vuejs.org>
  • Loading branch information
alexzhang1030 and yyx990803 committed Aug 7, 2024
1 parent 5753a10 commit e044b6e
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 3 deletions.
34 changes: 34 additions & 0 deletions packages/reactivity/__tests__/ref.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -478,4 +478,38 @@ describe('reactivity/ref', () => {
expect(toValue(c)).toBe(3)
expect(toValue(d)).toBe(4)
})

test('ref w/ customRef w/ getterRef w/ objectRef should store value cache', () => {
const refValue = ref(1)
// @ts-expect-error private field
expect(refValue._value).toBe(1)

let customRefValueCache = 0
const customRefValue = customRef((track, trigger) => {
return {
get() {
track()
return customRefValueCache
},
set(value: number) {
customRefValueCache = value
trigger()
},
}
})
customRefValue.value

// @ts-expect-error internal field
expect(customRefValue._value).toBe(0)

const getterRefValue = toRef(() => 1)
getterRefValue.value
// @ts-expect-error internal field
expect(getterRefValue._value).toBe(1)

const objectRefValue = toRef({ value: 1 }, 'value')
objectRefValue.value
// @ts-expect-error internal field
expect(objectRefValue._value).toBe(1)
})
})
11 changes: 8 additions & 3 deletions packages/reactivity/src/ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,8 @@ class CustomRefImpl<T> {

public readonly [ReactiveFlags.IS_REF] = true

public _value: T = undefined!

constructor(factory: CustomRefFactory<T>) {
const dep = (this.dep = new Dep())
const { get, set } = factory(dep.track.bind(dep), dep.trigger.bind(dep))
Expand All @@ -295,7 +297,7 @@ class CustomRefImpl<T> {
}

get value() {
return this._get()
return (this._value = this._get())
}

set value(newVal) {
Expand Down Expand Up @@ -339,6 +341,7 @@ export function toRefs<T extends object>(object: T): ToRefs<T> {

class ObjectRefImpl<T extends object, K extends keyof T> {
public readonly [ReactiveFlags.IS_REF] = true
public _value: T[K] = undefined!

constructor(
private readonly _object: T,
Expand All @@ -348,7 +351,7 @@ class ObjectRefImpl<T extends object, K extends keyof T> {

get value() {
const val = this._object[this._key]
return val === undefined ? this._defaultValue! : val
return (this._value = val === undefined ? this._defaultValue! : val)
}

set value(newVal) {
Expand All @@ -363,9 +366,11 @@ class ObjectRefImpl<T extends object, K extends keyof T> {
class GetterRefImpl<T> {
public readonly [ReactiveFlags.IS_REF] = true
public readonly [ReactiveFlags.IS_READONLY] = true
public _value: T = undefined!

constructor(private readonly _getter: () => T) {}
get value() {
return this._getter()
return (this._value = this._getter())
}
}

Expand Down

0 comments on commit e044b6e

Please sign in to comment.