Skip to content

Commit 09643c3

Browse files
authored
fix: Notify listeners when keys get removed (remove/clearAll) (#920)
* fix: Notify on key delete * Update HybridMMKV.cpp * update test for correctness
1 parent 3d3b793 commit 09643c3

File tree

3 files changed

+25
-7
lines changed

3 files changed

+25
-7
lines changed

example/__tests__/MMKV.harness.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -796,15 +796,13 @@ describe('MMKV Listeners & Observers', () => {
796796
// Wait for the listeners to trigger
797797
await waitForNextTick();
798798

799-
const changesBefore = changedKeys.length;
800-
801799
storage.clearAll();
802800

803-
// Wait for potential listeners to trigger (but they shouldn't for clearAll)
801+
// Wait for the listeners to trigger
804802
await waitForNextTick();
805803

806-
// clearAll should not trigger individual key change events
807-
expect(changedKeys.length).toStrictEqual(changesBefore);
804+
// We did 2x set and a clearAll (clears 2x keys)
805+
expect(changedKeys.length).toStrictEqual(4);
808806

809807
listener.remove();
810808
});

packages/react-native-mmkv/cpp/HybridMMKV.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,13 +145,23 @@ bool HybridMMKV::contains(const std::string& key) {
145145
return instance->containsKey(key);
146146
}
147147
bool HybridMMKV::remove(const std::string& key) {
148-
return instance->removeValueForKey(key);
148+
bool wasRemoved = instance->removeValueForKey(key);
149+
if (wasRemoved) {
150+
// Notify on changed
151+
MMKVValueChangedListenerRegistry::notifyOnValueChanged(instance->mmapID(), key);
152+
}
153+
return wasRemoved;
149154
}
150155
std::vector<std::string> HybridMMKV::getAllKeys() {
151156
return instance->allKeys();
152157
}
153158
void HybridMMKV::clearAll() {
159+
auto keysBefore = getAllKeys();
154160
instance->clearAll();
161+
for (const auto& key : keysBefore) {
162+
// Notify on changed
163+
MMKVValueChangedListenerRegistry::notifyOnValueChanged(instance->mmapID(), key);
164+
}
155165
}
156166
void HybridMMKV::recrypt(const std::optional<std::string>& key) {
157167
bool successful = false;

packages/react-native-mmkv/src/createMMKV/createMMKV.web.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,19 +80,29 @@ export function createMMKV(
8080
return `${keyPrefix}${key}`
8181
}
8282

83+
const callListeners = (key: string) => {
84+
listeners.forEach((l) => l(key))
85+
}
86+
8387
return {
8488
clearAll: () => {
8589
const keys = Object.keys(storage())
8690
for (const key of keys) {
8791
if (key.startsWith(keyPrefix)) {
8892
storage().removeItem(key)
93+
callListeners(key)
8994
}
9095
}
9196
},
92-
remove: (key) => storage().removeItem(prefixedKey(key)) ?? false,
97+
remove: (key) => {
98+
const wasRemoved = storage().removeItem(prefixedKey(key)) ?? false
99+
if (wasRemoved) callListeners(key)
100+
return wasRemoved
101+
},
93102
set: (key, value) => {
94103
if (key === '') throw new Error('Cannot set a value for an empty key!')
95104
storage().setItem(prefixedKey(key), value.toString())
105+
callListeners(key)
96106
},
97107
getString: (key) => storage().getItem(prefixedKey(key)) ?? undefined,
98108
getNumber: (key) => {

0 commit comments

Comments
 (0)