Browse Source

fix(reactivity): Map.set should trigger when adding new entry with undefined value (#364)

Cr 6 years ago
parent
commit
246cad7459

+ 8 - 5
packages/reactivity/__tests__/collections/Map.spec.ts

@@ -185,21 +185,24 @@ describe('reactivity/collections', () => {
 
       expect(dummy).toBe(undefined)
       expect(mapSpy).toHaveBeenCalledTimes(1)
+      map.set('key', undefined)
+      expect(dummy).toBe(undefined)
+      expect(mapSpy).toHaveBeenCalledTimes(2)
       map.set('key', 'value')
       expect(dummy).toBe('value')
-      expect(mapSpy).toHaveBeenCalledTimes(2)
+      expect(mapSpy).toHaveBeenCalledTimes(3)
       map.set('key', 'value')
       expect(dummy).toBe('value')
-      expect(mapSpy).toHaveBeenCalledTimes(2)
+      expect(mapSpy).toHaveBeenCalledTimes(3)
       map.delete('key')
       expect(dummy).toBe(undefined)
-      expect(mapSpy).toHaveBeenCalledTimes(3)
+      expect(mapSpy).toHaveBeenCalledTimes(4)
       map.delete('key')
       expect(dummy).toBe(undefined)
-      expect(mapSpy).toHaveBeenCalledTimes(3)
+      expect(mapSpy).toHaveBeenCalledTimes(4)
       map.clear()
       expect(dummy).toBe(undefined)
-      expect(mapSpy).toHaveBeenCalledTimes(3)
+      expect(mapSpy).toHaveBeenCalledTimes(4)
     })
 
     it('should not observe raw data', () => {

+ 7 - 4
packages/reactivity/__tests__/collections/WeakMap.spec.ts

@@ -46,18 +46,21 @@ describe('reactivity/collections', () => {
 
       expect(dummy).toBe(undefined)
       expect(mapSpy).toHaveBeenCalledTimes(1)
+      map.set(key, undefined)
+      expect(dummy).toBe(undefined)
+      expect(mapSpy).toHaveBeenCalledTimes(2)
       map.set(key, 'value')
       expect(dummy).toBe('value')
-      expect(mapSpy).toHaveBeenCalledTimes(2)
+      expect(mapSpy).toHaveBeenCalledTimes(3)
       map.set(key, 'value')
       expect(dummy).toBe('value')
-      expect(mapSpy).toHaveBeenCalledTimes(2)
+      expect(mapSpy).toHaveBeenCalledTimes(3)
       map.delete(key)
       expect(dummy).toBe(undefined)
-      expect(mapSpy).toHaveBeenCalledTimes(3)
+      expect(mapSpy).toHaveBeenCalledTimes(4)
       map.delete(key)
       expect(dummy).toBe(undefined)
-      expect(mapSpy).toHaveBeenCalledTimes(3)
+      expect(mapSpy).toHaveBeenCalledTimes(4)
     })
 
     it('should not observe raw data', () => {

+ 13 - 15
packages/reactivity/src/collectionHandlers.ts

@@ -68,21 +68,19 @@ function set(this: MapTypes, key: unknown, value: unknown) {
   const hadKey = proto.has.call(target, key)
   const oldValue = proto.get.call(target, key)
   const result = proto.set.call(target, key, value)
-  if (value !== oldValue) {
-    /* istanbul ignore else */
-    if (__DEV__) {
-      const extraInfo = { oldValue, newValue: value }
-      if (!hadKey) {
-        trigger(target, OperationTypes.ADD, key, extraInfo)
-      } else {
-        trigger(target, OperationTypes.SET, key, extraInfo)
-      }
-    } else {
-      if (!hadKey) {
-        trigger(target, OperationTypes.ADD, key)
-      } else {
-        trigger(target, OperationTypes.SET, key)
-      }
+  /* istanbul ignore else */
+  if (__DEV__) {
+    const extraInfo = { oldValue, newValue: value }
+    if (!hadKey) {
+      trigger(target, OperationTypes.ADD, key, extraInfo)
+    } else if (value !== oldValue) {
+      trigger(target, OperationTypes.SET, key, extraInfo)
+    }
+  } else {
+    if (!hadKey) {
+      trigger(target, OperationTypes.ADD, key)
+    } else if (value !== oldValue) {
+      trigger(target, OperationTypes.SET, key)
     }
   }
   return result