Closed
Description
When executing mergeCollection
, Onyx calls the collection subscriber callback and all the collection items subscribers callbacks, even if those items did not change.
As a result, if there is a React component subscribed to a single collection item (e.g. a specific Report) and uses this item as a hook dependency (e.g. useEffect(..., [report])
), the hook is executed every time the collection is merged, even if this specific item did not change.
Suggested solution: call individual collection item subscribers only if the item changes.
Example unit test that should succeed:
it('should not call a collection item subscriber if the value did not change', () => {
const connectionIDs = [];
const cat = `${ONYX_KEYS.COLLECTION.ANIMALS}cat`;
const dog = `${ONYX_KEYS.COLLECTION.ANIMALS}dog`;
const collectionCallback = jest.fn();
const catCallback = jest.fn();
const dogCallback = jest.fn();
connectionIDs.push(
Onyx.connect({
key: ONYX_KEYS.COLLECTION.ANIMALS,
callback: collectionCallback,
waitForCollectionCallback: true,
}),
);
connectionIDs.push(Onyx.connect({key: cat, callback: catCallback}));
connectionIDs.push(Onyx.connect({key: dog, callback: dogCallback}));
const initialValue = { name: 'Fluffy' };
const collectionToMerge = {
[cat]: initialValue,
[dog]: { name: 'Rex' },
};
return Onyx.set(cat, initialValue)
.then(() => {
Onyx.mergeCollection(ONYX_KEYS.COLLECTION.ANIMALS, collectionToMerge);
return waitForPromisesToResolve();
})
.then(() => {
expect(collectionCallback).toHaveBeenCalledTimes(3);
expect(collectionCallback).toHaveBeenCalledWith({
[cat]: initialValue,
[dog]: { name: 'Rex' },
});
expect(catCallback).toHaveBeenCalledTimes(2);
expect(dogCallback).toHaveBeenCalledTimes(2);
Onyx.disconnect(connectionIDs);
});
});
Metadata
Metadata
Assignees
Labels
No labels