From eb34b2def660c81b7cbe69b670dd26dc8a4ce1dd Mon Sep 17 00:00:00 2001 From: Janry Date: Wed, 3 Nov 2021 15:56:40 +0800 Subject: [PATCH] fix(reactive): fix computed value can not get real value (#2389) --- packages/core/src/models/Field.ts | 5 +++-- .../reactive/src/__tests__/autorun.spec.ts | 21 +++++++++++++++++++ packages/reactive/src/handlers.ts | 4 ++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/packages/core/src/models/Field.ts b/packages/core/src/models/Field.ts index 0dea099e47b..319323fbd5e 100644 --- a/packages/core/src/models/Field.ts +++ b/packages/core/src/models/Field.ts @@ -233,13 +233,14 @@ export class Field< reaction( () => this.display, (display) => { + const value = this.value if (display === 'visible') { - if (isEmpty(this.value)) { + if (isEmpty(value)) { this.setValue(this.caches.value) this.caches.value = undefined } } else { - this.caches.value = toJS(this.value) + this.caches.value = toJS(value) if (display === 'none') { this.form.deleteValuesIn(this.path) } diff --git a/packages/reactive/src/__tests__/autorun.spec.ts b/packages/reactive/src/__tests__/autorun.spec.ts index e5576adb4e8..301c1a29cc3 100644 --- a/packages/reactive/src/__tests__/autorun.spec.ts +++ b/packages/reactive/src/__tests__/autorun.spec.ts @@ -542,3 +542,24 @@ test('autorun dispose in batch', () => { }) expect(handler).toBeCalledTimes(1) }) + +test('atom mutate value by computed depend', () => { + const obs = observable({}) + const comp1 = observable.computed(() => { + return obs.aa?.bb + }) + const comp2 = observable.computed(() => { + return obs.aa?.cc + }) + const handler = jest.fn() + autorun(() => { + handler(comp1.value, comp2.value) + }) + obs.aa = { + bb: 123, + cc: 321, + } + expect(handler).toBeCalledTimes(2) + expect(handler).toBeCalledWith(undefined, undefined) + expect(handler).toBeCalledWith(123, 321) +}) diff --git a/packages/reactive/src/handlers.ts b/packages/reactive/src/handlers.ts index 991478c2bfc..8cc58b38d3d 100644 --- a/packages/reactive/src/handlers.ts +++ b/packages/reactive/src/handlers.ts @@ -1,4 +1,6 @@ import { + batchEnd, + batchStart, bindTargetKeyWithCurrentReaction, runReactionsFromTargetKey, } from './reaction' @@ -200,6 +202,7 @@ export const baseHandlers: ProxyHandler = { const newValue = createObservable(target, key, value) const oldValue = target[key] target[key] = newValue // use Reflect.set is too slow + batchStart() if (!hadKey) { runReactionsFromTargetKey({ target, @@ -219,6 +222,7 @@ export const baseHandlers: ProxyHandler = { type: 'set', }) } + batchEnd() return true }, deleteProperty(target, key) {