Skip to content

fix(reactivity): ensure get the latest value when reading the compute #6744

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions packages/reactivity/__tests__/deferredComputed.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,32 @@ describe('deferred computed', () => {
expect(effectSpy).toHaveBeenCalledTimes(2)
})

test('sync access to computed property should get the latest value', () => {
const bSpy = jest.fn()
const c1Spy = jest.fn()
const c2Spy = jest.fn()

const a = ref(0)
const b = deferredComputed(() => {
bSpy()
return a.value
})
const c1 = deferredComputed(() => {
c1Spy()
return b.value
})
const c2 = computed(() => {
c2Spy()
return b.value
})
// emit computed getter
c1.value;c2.value;
a.value = 2
// sync access
expect(c1.value).toEqual(2)
expect(c2.value).toEqual(2)
})

test('should not compute if deactivated before scheduler is called', async () => {
const c1Spy = jest.fn()
const src = ref(0)
Expand Down
17 changes: 12 additions & 5 deletions packages/reactivity/src/computed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,19 @@ export class ComputedRefImpl<T> {
isReadonly: boolean,
isSSR: boolean
) {
this.effect = new ReactiveEffect(getter, () => {
if (!this._dirty) {
this._dirty = true
triggerRefValue(this)
this.effect = new ReactiveEffect(
getter,
(deferredComputedTrigger?: boolean) => {
if (deferredComputedTrigger) {
this._dirty = true
}else{
if (!this._dirty) {
this._dirty = true
}
triggerRefValue(this)
}
}
})
)
this.effect.computed = this
this.effect.active = this._cacheable = !isSSR
this[ReactiveFlags.IS_READONLY] = isReadonly
Expand Down
2 changes: 1 addition & 1 deletion packages/reactivity/src/deferredComputed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class DeferredComputedRefImpl<T> {
// value invalidation in case of sync access; normal effects are
// deferred to be triggered in scheduler.
for (const e of this.dep) {
if (e.computed instanceof DeferredComputedRefImpl) {
if (e.computed) {
e.scheduler!(true /* computedTrigger */)
}
}
Expand Down