[FIX] reactivity: do not notify for NOOPs on collections

Previously, if a reactive was observing the presence of an item in a
set that was originally not present, it would get notified when that
item was "deleted" from the set (even though there was nothing to delete
and the set did not change). The same applied to the key already being
present and then being "added". The same thing occured with Map, both
for presence but also for values (setting a key to the value it was
already set to would notify).

This commit fixes that.
This commit is contained in:
Samuel Degueldre
2023-09-22 14:13:07 +02:00
committed by Géry Debongnie
parent e7ebb92104
commit 3937966b74
2 changed files with 19 additions and 1 deletions
+1 -1
View File
@@ -368,7 +368,7 @@ function delegateAndNotify(
if (hadKey !== hasKey) {
notifyReactives(target, KEYCHANGES);
}
if (originalValue !== value) {
if (originalValue !== target[getterName](key)) {
notifyReactives(target, key);
}
return ret;
+18
View File
@@ -1292,6 +1292,12 @@ describe("Collections", () => {
state.add(3); // setting unobserved key doesn't notify
expect(observer).toHaveBeenCalledTimes(3);
expect(state.has(3)).toBe(true); // subscribe to 3
state.add(3); // adding observed key doesn't notify if key was already present
expect(observer).toHaveBeenCalledTimes(3);
expect(state.has(4)).toBe(false); // subscribe to 4
state.delete(4); // deleting observed key doesn't notify if key was already not present
expect(observer).toHaveBeenCalledTimes(3);
});
test("iterating on keys returns reactives", async () => {
@@ -1485,6 +1491,12 @@ describe("Collections", () => {
state.set(3, 4); // setting unobserved key doesn't notify
expect(observer).toHaveBeenCalledTimes(3);
expect(state.has(3)).toBe(true); // subscribe to 3
state.set(3, 4); // setting the same value doesn't notify
expect(observer).toHaveBeenCalledTimes(3);
expect(state.has(4)).toBe(false); // subscribe to 4
state.delete(4); // deleting observed key doesn't notify if key was already not present
expect(observer).toHaveBeenCalledTimes(3);
});
test("checking for a key with 'get' subscribes the callback to changes to that key", () => {
@@ -1510,6 +1522,12 @@ describe("Collections", () => {
state.set(3, 4); // setting unobserved key doesn't notify
expect(observer).toHaveBeenCalledTimes(3);
expect(state.get(3)).toBe(4); // subscribe to 3
state.set(3, 4); // setting the same value doesn't notify
expect(observer).toHaveBeenCalledTimes(3);
expect(state.get(4)).toBe(undefined); // subscribe to 4
state.delete(4); // deleting observed key doesn't notify if key was already not present
expect(observer).toHaveBeenCalledTimes(3);
});
test("getting values returns a reactive", async () => {