Skip to content

Commit 9db1607

Browse files
committed
Fix waitForCollectionCallback
1 parent 1f58aa5 commit 9db1607

2 files changed

Lines changed: 79 additions & 0 deletions

File tree

README.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,70 @@ export default withOnyx({
137137

138138
It is preferable to use the HOC over `Onyx.connect()` in React code as `withOnyx()` will delay the rendering of the wrapped component until all keys have been accessed and made available.
139139

140+
## Collections
141+
142+
Collections allow keys with similar value types to be subscribed together by subscribing to the collection key. To define one, it must be included in the `ONYXKEYS.COLLECTION` object and it must be suffixed with an underscore. Member keys should use a unique identifier or index after the collection key prefix (e.g. `chat_42`).
143+
144+
```javascript
145+
const ONYXKEYS = {
146+
COLLECTION: {
147+
CHAT: 'chat_',
148+
},
149+
};
150+
```
151+
152+
### Setting Collection Values
153+
154+
To save a new collection key we can either do:
155+
156+
```js
157+
Onyx.merge(`${ONYXKEYS.COLLECTION.CHAT}${chat1.id}`, chat1);
158+
```
159+
160+
or we can set many at once with `mergeCollection()`:
161+
162+
```js
163+
Onyx.mergeCollection(ONYXKEYS.COLLECTION.CHAT, {
164+
[`${ONYXKEYS.COLLECTION.CHAT}${chat1.id}`]: chat1,
165+
[`${ONYXKEYS.COLLECTION.CHAT}${chat2.id}`]: chat2,
166+
[`${ONYXKEYS.COLLECTION.CHAT}${chat3.id}`]: chat3,
167+
});
168+
```
169+
170+
### Subscribing to Collections
171+
172+
There are several ways to subscribe to these keys:
173+
174+
```javascript
175+
withOnyx({
176+
allChats: {key: ONYXKEYS.COLLECTION.CHAT},
177+
})(MyComponent);
178+
```
179+
180+
This will return the initial collection as an object of collection member key/values. Changes to the individual member keys will modify the entire object and new props will be passed with each individual key update.
181+
182+
```js
183+
Onyx.connect({key: ONYXKEYS.COLLECTION.CHAT}, callback: (memberValue, memberKey) => {...}});
184+
```
185+
186+
This will fire the callback `n` times depending on how many collection member keys have been stored. Changes to those keys after the initial callbacks fire will occur when each individual key is updated.
187+
188+
```js
189+
Onyx.connect({
190+
key: ONYXKEYS.COLLECTION.CHAT,
191+
waitForCollectionCallback: true,
192+
callback: (allChats) => {...}},
193+
});
194+
```
195+
196+
This final option forces `Onyx.connect()` to behave more like `withOnyx()` and only update the callback once with the entire collection initially and later with an updated version of the collection when individual keys update.
197+
198+
### Performance Considerations When Using Collections
199+
200+
Be cautious when using collections as things can get out of hand if you have a subscriber hooked up to a collection key that has large numbers of individual keys. If this is the case, it is critical to use `mergeCollection()` over `merge()`.
201+
202+
Remember, `mergeCollection()` will notify a subscriber only *once* with the total collected values whereas each call to `Onyx.merge()` would re-render a connected component `n` times per key that you call it on.
203+
140204
## Clean up
141205

142206
To clear all data from `Onyx` we can use `Onyx.clear()`.

lib/Onyx.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,15 @@ function keysChanged(collectionKey, collection) {
253253
return;
254254
}
255255

256+
/**
257+
* e.g. Onyx.connect({key: ONYXKEYS.COLLECTION.REPORT, callback: ...});
258+
*/
256259
const isSubscribedToCollectionKey = isKeyMatch(subscriber.key, collectionKey)
257260
&& isCollectionKey(subscriber.key);
261+
262+
/**
263+
* e.g. Onyx.connect({key: `${ONYXKEYS.COLLECTION.REPORT}{reportID}`, callback: ...});
264+
*/
258265
const isSubscribedToCollectionMemberKey = subscriber.key.startsWith(collectionKey);
259266

260267
if (isSubscribedToCollectionKey) {
@@ -328,7 +335,15 @@ function keyChanged(key, data) {
328335
}
329336

330337
if (_.isFunction(subscriber.callback)) {
338+
if (subscriber.waitForCollectionCallback) {
339+
const cachedCollection = getCachedCollection(subscriber.key);
340+
cachedCollection[key] = data;
341+
subscriber.callback(cachedCollection);
342+
return;
343+
}
344+
331345
subscriber.callback(data, key);
346+
return;
332347
}
333348

334349
if (!subscriber.withOnyxInstance) {

0 commit comments

Comments
 (0)