From 5521527cf44cdbc121023573bced9d4bebe416b2 Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Fri, 24 Jul 2020 17:19:21 +0100 Subject: [PATCH] fix: make sure changing an undefined value to undefined is not picked up as change. Fixes #646 --- __tests__/regressions.js | 20 ++++++++++++++++++++ src/core/proxy.ts | 7 ++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/__tests__/regressions.js b/__tests__/regressions.js index 9c5bae33..e0fc30b1 100644 --- a/__tests__/regressions.js +++ b/__tests__/regressions.js @@ -78,5 +78,25 @@ function runBaseTest(name, useProxies, autoFreeze, useListener) { x: 1 }) }) + + test("#646 setting undefined field to undefined should not create new result", () => { + const foo = { + bar: undefined + } + const foo2 = produce(foo, draft => { + draft.bar = undefined + }) + expect(foo2).toBe(foo) + }) + + test("#646 -2 setting undefined field to undefined should not create new result", () => { + const foo = {} + const foo2 = produce(foo, draft => { + draft.bar = undefined + }) + expect(foo2).not.toBe(foo) + expect(foo).toEqual({}) + expect(foo2).toEqual({bar: undefined}) + }) }) } diff --git a/src/core/proxy.ts b/src/core/proxy.ts index 94b89f85..13140a5c 100644 --- a/src/core/proxy.ts +++ b/src/core/proxy.ts @@ -139,7 +139,12 @@ export const objectTraps: ProxyHandler = { } state.assigned_[prop] = true if (!state.modified_) { - if (is(value, peek(latest(state), prop)) && value !== undefined) + // the last check is because we need to be able to distinguish setting a non-existig to undefined (which is a change) + // from setting an existing property with value undefined to undefined (which is not a change) + if ( + is(value, peek(latest(state), prop)) && + (value !== undefined || has(state.base_, prop)) + ) return true prepareCopy(state) markChanged(state)