Browse Source

fix(reactivity): trigger iteration effect on Map.set

fix #709
Evan You 6 years ago
parent
commit
e1c9153b9e

+ 13 - 0
packages/reactivity/__tests__/collections/Map.spec.ts

@@ -74,6 +74,9 @@ describe('reactivity/collections', () => {
       expect(dummy).toBe(3)
       expect(dummy).toBe(3)
       map.set('key2', 2)
       map.set('key2', 2)
       expect(dummy).toBe(5)
       expect(dummy).toBe(5)
+      // iteration should track mutation of existing entries (#709)
+      map.set('key1', 4)
+      expect(dummy).toBe(6)
       map.delete('key1')
       map.delete('key1')
       expect(dummy).toBe(2)
       expect(dummy).toBe(2)
       map.clear()
       map.clear()
@@ -93,6 +96,9 @@ describe('reactivity/collections', () => {
       expect(dummy).toBe(3)
       expect(dummy).toBe(3)
       map.set('key2', 2)
       map.set('key2', 2)
       expect(dummy).toBe(5)
       expect(dummy).toBe(5)
+      // iteration should track mutation of existing entries (#709)
+      map.set('key1', 4)
+      expect(dummy).toBe(6)
       map.delete('key1')
       map.delete('key1')
       expect(dummy).toBe(2)
       expect(dummy).toBe(2)
       map.clear()
       map.clear()
@@ -135,6 +141,9 @@ describe('reactivity/collections', () => {
       expect(dummy).toBe(3)
       expect(dummy).toBe(3)
       map.set('key2', 2)
       map.set('key2', 2)
       expect(dummy).toBe(5)
       expect(dummy).toBe(5)
+      // iteration should track mutation of existing entries (#709)
+      map.set('key1', 4)
+      expect(dummy).toBe(6)
       map.delete('key1')
       map.delete('key1')
       expect(dummy).toBe(2)
       expect(dummy).toBe(2)
       map.clear()
       map.clear()
@@ -163,6 +172,10 @@ describe('reactivity/collections', () => {
       map.set('key2', 2)
       map.set('key2', 2)
       expect(dummy).toBe('key1key2')
       expect(dummy).toBe('key1key2')
       expect(dummy2).toBe(5)
       expect(dummy2).toBe(5)
+      // iteration should track mutation of existing entries (#709)
+      map.set('key1', 4)
+      expect(dummy).toBe('key1key2')
+      expect(dummy2).toBe(6)
       map.delete('key1')
       map.delete('key1')
       expect(dummy).toBe('key2')
       expect(dummy).toBe('key2')
       expect(dummy2).toBe(2)
       expect(dummy2).toBe(2)

+ 6 - 2
packages/reactivity/src/effect.ts

@@ -184,8 +184,12 @@ export function trigger(
     if (key !== void 0) {
     if (key !== void 0) {
       addRunners(effects, computedRunners, depsMap.get(key))
       addRunners(effects, computedRunners, depsMap.get(key))
     }
     }
-    // also run for iteration key on ADD | DELETE
-    if (type === TriggerOpTypes.ADD || type === TriggerOpTypes.DELETE) {
+    // also run for iteration key on ADD | DELETE | Map.SET
+    if (
+      type === TriggerOpTypes.ADD ||
+      type === TriggerOpTypes.DELETE ||
+      (type === TriggerOpTypes.SET && target instanceof Map)
+    ) {
       const iterationKey = isArray(target) ? 'length' : ITERATE_KEY
       const iterationKey = isArray(target) ? 'length' : ITERATE_KEY
       addRunners(effects, computedRunners, depsMap.get(iterationKey))
       addRunners(effects, computedRunners, depsMap.get(iterationKey))
     }
     }