From e044b6e737efc9433d1d84590036b82280da6292 Mon Sep 17 00:00:00 2001 From: Alex <49969959+alexzhang1030@users.noreply.github.com> Date: Wed, 7 Aug 2024 22:24:28 +0800 Subject: [PATCH] feat(reactivity): store value cache on CustomRefs impls (#11539) Co-authored-by: Evan You --- packages/reactivity/__tests__/ref.spec.ts | 34 +++++++++++++++++++++++ packages/reactivity/src/ref.ts | 11 ++++++-- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/packages/reactivity/__tests__/ref.spec.ts b/packages/reactivity/__tests__/ref.spec.ts index a3f56ab05c2..0158ca0f64a 100644 --- a/packages/reactivity/__tests__/ref.spec.ts +++ b/packages/reactivity/__tests__/ref.spec.ts @@ -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) + }) }) diff --git a/packages/reactivity/src/ref.ts b/packages/reactivity/src/ref.ts index 87b613e5773..34f9965fd9e 100644 --- a/packages/reactivity/src/ref.ts +++ b/packages/reactivity/src/ref.ts @@ -287,6 +287,8 @@ class CustomRefImpl { public readonly [ReactiveFlags.IS_REF] = true + public _value: T = undefined! + constructor(factory: CustomRefFactory) { const dep = (this.dep = new Dep()) const { get, set } = factory(dep.track.bind(dep), dep.trigger.bind(dep)) @@ -295,7 +297,7 @@ class CustomRefImpl { } get value() { - return this._get() + return (this._value = this._get()) } set value(newVal) { @@ -339,6 +341,7 @@ export function toRefs(object: T): ToRefs { class ObjectRefImpl { public readonly [ReactiveFlags.IS_REF] = true + public _value: T[K] = undefined! constructor( private readonly _object: T, @@ -348,7 +351,7 @@ class ObjectRefImpl { 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) { @@ -363,9 +366,11 @@ class ObjectRefImpl { class GetterRefImpl { 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()) } }