diff --git a/src/core/computedvalue.ts b/src/core/computedvalue.ts index 8e9826d7a..7da1fafa7 100644 --- a/src/core/computedvalue.ts +++ b/src/core/computedvalue.ts @@ -197,13 +197,19 @@ export class ComputedValue implements IObservable, IComputedValue, IDeriva const oldValue = this.value const wasSuspended = /* see #1208 */ this.dependenciesState === IDerivationState.NOT_TRACKING - const newValue = (this.value = this.computeValue(true)) - return ( + const newValue = this.computeValue(true) + + const changed = wasSuspended || isCaughtException(oldValue) || isCaughtException(newValue) || !this.equals(oldValue, newValue) - ) + + if (changed) { + this.value = newValue + } + + return changed } computeValue(track: boolean) { diff --git a/test/base/babel-tests.js b/test/base/babel-tests.js index 4d78789b4..d5f20c4f6 100644 --- a/test/base/babel-tests.js +++ b/test/base/babel-tests.js @@ -102,6 +102,29 @@ test("babel: parameterized computed decorator", () => { expect(changes).toEqual([{ sum: 6 }, { sum: 7 }, { sum: 9 }]) }) +test("computed value should be the same around changing which was considered equivalent", () => { + class TestClass { + @observable c = null + defaultCollection = [] + @computed.struct + get collection() { + return this.c || this.defaultCollection + } + } + + const t1 = new TestClass() + + const d = autorun(() => t1.collection) + + const oldCollection = t1.collection + t1.c = [] + const newCollection = t1.collection + + expect(oldCollection).toBe(newCollection) + + d() +}) + class Order { @observable price = 3 @observable amount = 2