Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Onyx: keyChanged improvement - patch #36008

Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions patches/react-native-onyx+1.0.118.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
diff --git a/node_modules/react-native-onyx/lib/Onyx.js b/node_modules/react-native-onyx/lib/Onyx.js
index 9212df3..ff14d02 100644
--- a/node_modules/react-native-onyx/lib/Onyx.js
+++ b/node_modules/react-native-onyx/lib/Onyx.js
@@ -29,6 +29,9 @@ let lastConnectionID = 0;
// Holds a mapping of all the react components that want their state subscribed to a store key
const callbackToStateMapping = {};

+// Holds a mapping of the connected key to the connectionID for faster lookups
+const onyxKeyToConnectionIDs = new Map();
+
// Keeps a copy of the values of the onyx collection keys as a map for faster lookups
let onyxCollectionKeyMap = new Map();

@@ -387,7 +390,13 @@ function keysChanged(collectionKey, partialCollection, notifyRegularSubscibers =
// We are iterating over all subscribers similar to keyChanged(). However, we are looking for subscribers who are subscribing to either a collection key or
// individual collection key member for the collection that is being updated. It is important to note that the collection parameter cane be a PARTIAL collection
// and does not represent all of the combined keys and values for a collection key. It is just the "new" data that was merged in via mergeCollection().
- const stateMappingKeys = _.keys(callbackToStateMapping);
+ const stateMappingKeys = onyxKeyToConnectionIDs.get(collectionKey);
+
+ // If the key was not found in the mapping then we can skip notifying subscribers
+ if (!stateMappingKeys) {
+ return;
+ }
+
for (let i = 0; i < stateMappingKeys.length; i++) {
const subscriber = callbackToStateMapping[stateMappingKeys[i]];
if (!subscriber) {
@@ -563,7 +572,13 @@ function keyChanged(key, data, canUpdateSubscriber, notifyRegularSubscibers = tr
// We are iterating over all subscribers to see if they are interested in the key that has just changed. If the subscriber's key is a collection key then we will
// notify them if the key that changed is a collection member. Or if it is a regular key notify them when there is an exact match. Depending on whether the subscriber
// was connected via withOnyx we will call setState() directly on the withOnyx instance. If it is a regular connection we will pass the data to the provided callback.
- const stateMappingKeys = _.keys(callbackToStateMapping);
+ const stateMappingKeys = onyxKeyToConnectionIDs.get(key);
+
+ // If the key was not found in the mapping then we can skip notifying subscribers
+ if (!stateMappingKeys) {
+ return;
+ }
+
for (let i = 0; i < stateMappingKeys.length; i++) {
const subscriber = callbackToStateMapping[stateMappingKeys[i]];
if (!subscriber || !isKeyMatch(subscriber.key, key) || (_.isFunction(canUpdateSubscriber) && !canUpdateSubscriber(subscriber))) {
@@ -799,6 +814,11 @@ function connect(mapping) {
callbackToStateMapping[connectionID] = mapping;
callbackToStateMapping[connectionID].connectionID = connectionID;

+ if (!onyxKeyToConnectionIDs.has(mapping.key)) {
+ onyxKeyToConnectionIDs.set(mapping.key, []);
+ }
+ onyxKeyToConnectionIDs.get(mapping.key).push(connectionID);
+
if (mapping.initWithStoredValues === false) {
return connectionID;
}
@@ -902,6 +922,14 @@ function disconnect(connectionID, keyToRemoveFromEvictionBlocklist) {
removeFromEvictionBlockList(keyToRemoveFromEvictionBlocklist, connectionID);
}

+ const subscriber = callbackToStateMapping[connectionID];
+ const keyToDelete = subscriber.key;
+
+ if (onyxKeyToConnectionIDs.has(keyToDelete)) {
+ onyxKeyToConnectionIDs.set(keyToDelete, _.without(onyxKeyToConnectionIDs.get(keyToDelete), connectionID));
+ }
+
+
delete callbackToStateMapping[connectionID];
}

Loading