diff --git a/packages/reactive/src/__tests__/autorun.spec.ts b/packages/reactive/src/__tests__/autorun.spec.ts index 2e74766b38a..c9cfe08a4a6 100644 --- a/packages/reactive/src/__tests__/autorun.spec.ts +++ b/packages/reactive/src/__tests__/autorun.spec.ts @@ -741,3 +741,19 @@ test('reaction recollect dependencies', () => { expect(fn2).toBeCalledTimes(2) expect(trigger2).toBeCalledTimes(2) }) + +test('avoid unnecessary reaction', () => { + const obs = observable({ + aa: { v: 1 }, + }) + const fn1 = jest.fn() + + reaction(() => { + fn1() + return obs.aa.v + }) + + obs.aa = obs.aa + + expect(fn1).toBeCalledTimes(1) +}) diff --git a/packages/reactive/src/handlers.ts b/packages/reactive/src/handlers.ts index 62db006479f..20a5676e907 100644 --- a/packages/reactive/src/handlers.ts +++ b/packages/reactive/src/handlers.ts @@ -207,7 +207,12 @@ export const baseHandlers: ProxyHandler = { } const hadKey = hasOwnProperty.call(target, key) const newValue = createObservable(target, key, value) - const oldValue = target[key] + + // If the old value has already generated an observable result, + // directly use observableResult compapre to value to avoid unnecessary reactions + const observableResult = RawProxy.get(target[key]) + const oldValue = observableResult ? observableResult : target[key] + target[key] = newValue // use Reflect.set is too slow if (!hadKey) { runReactionsFromTargetKey({