Skip to content

Commit ca1d0d5

Browse files
committed
update id to undefined if it is empty
1 parent 35368fa commit ca1d0d5

1 file changed

Lines changed: 26 additions & 18 deletions

File tree

lib/useOnyx.ts

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,11 @@ function useOnyx<TKey extends OnyxKey, TReturnValue = OnyxValue<TKey>>(
9595
dependencies: DependencyList = [],
9696
): UseOnyxResult<TReturnValue> {
9797
const connectionRef = useRef<Connection | null>(null);
98-
const previousKey = usePrevious(key);
98+
let updatedKey = key;
99+
if (OnyxUtils.isCollectionKey(key) && key.endsWith('_')) {
100+
updatedKey = `${key}undefined` as TKey;
101+
}
102+
const previousKey = usePrevious(updatedKey);
99103

100104
// Used to stabilize the selector reference and avoid unnecessary calls to `getSnapshot()`.
101105
const selectorRef = useLiveRef(options?.selector);
@@ -135,27 +139,31 @@ function useOnyx<TKey extends OnyxKey, TReturnValue = OnyxValue<TKey>>(
135139

136140
useEffect(() => {
137141
// These conditions will ensure we can only handle dynamic collection member keys from the same collection.
138-
if (options?.allowDynamicKey || previousKey === key) {
142+
if (options?.allowDynamicKey || previousKey === updatedKey) {
139143
return;
140144
}
141145

142146
try {
143147
const previousCollectionKey = OnyxUtils.splitCollectionMemberKey(previousKey)[0];
144-
const collectionKey = OnyxUtils.splitCollectionMemberKey(key)[0];
148+
const collectionKey = OnyxUtils.splitCollectionMemberKey(updatedKey)[0];
145149

146-
if (OnyxUtils.isCollectionMemberKey(previousCollectionKey, previousKey) && OnyxUtils.isCollectionMemberKey(collectionKey, key) && previousCollectionKey === collectionKey) {
150+
if (
151+
OnyxUtils.isCollectionMemberKey(previousCollectionKey, previousKey) &&
152+
OnyxUtils.isCollectionMemberKey(collectionKey, updatedKey) &&
153+
previousCollectionKey === collectionKey
154+
) {
147155
return;
148156
}
149157
} catch (e) {
150158
throw new Error(
151-
`'${previousKey}' key can't be changed to '${key}'. useOnyx() only supports dynamic keys if they are both collection member keys from the same collection e.g. from 'collection_id1' to 'collection_id2'.`,
159+
`'${previousKey}' key can't be changed to '${updatedKey}'. useOnyx() only supports dynamic keys if they are both collection member keys from the same collection e.g. from 'collection_id1' to 'collection_id2'.`,
152160
);
153161
}
154162

155163
throw new Error(
156-
`'${previousKey}' key can't be changed to '${key}'. useOnyx() only supports dynamic keys if they are both collection member keys from the same collection e.g. from 'collection_id1' to 'collection_id2'.`,
164+
`'${previousKey}' key can't be changed to '${updatedKey}'. useOnyx() only supports dynamic keys if they are both collection member keys from the same collection e.g. from 'collection_id1' to 'collection_id2'.`,
157165
);
158-
}, [previousKey, key, options?.allowDynamicKey]);
166+
}, [previousKey, updatedKey, options?.allowDynamicKey]);
159167

160168
useEffect(() => {
161169
// This effect will only run if the `dependencies` array changes. If it changes it will force the hook
@@ -176,16 +184,16 @@ function useOnyx<TKey extends OnyxKey, TReturnValue = OnyxValue<TKey>>(
176184
return;
177185
}
178186

179-
if (!OnyxCache.isEvictableKey(key)) {
180-
throw new Error(`canEvict can't be used on key '${key}'. This key must explicitly be flagged as safe for removal by adding it to Onyx.init({evictableKeys: []}).`);
187+
if (!OnyxCache.isEvictableKey(updatedKey)) {
188+
throw new Error(`canEvict can't be used on key '${updatedKey}'. This key must explicitly be flagged as safe for removal by adding it to Onyx.init({evictableKeys: []}).`);
181189
}
182190

183191
if (options.canEvict) {
184192
connectionManager.removeFromEvictionBlockList(connectionRef.current);
185193
} else {
186194
connectionManager.addToEvictionBlockList(connectionRef.current);
187195
}
188-
}, [key, options?.canEvict]);
196+
}, [updatedKey, options?.canEvict]);
189197

190198
const getSnapshot = useCallback(() => {
191199
let isOnyxValueDefined = true;
@@ -200,7 +208,7 @@ function useOnyx<TKey extends OnyxKey, TReturnValue = OnyxValue<TKey>>(
200208
// update `newValueRef` when `Onyx.connect()` callback is fired.
201209
if (isFirstConnectionRef.current || shouldGetCachedValueRef.current) {
202210
// Gets the value from cache and maps it with selector. It changes `null` to `undefined` for `useOnyx` compatibility.
203-
const value = OnyxUtils.tryGetCachedValue(key) as OnyxValue<TKey>;
211+
const value = OnyxUtils.tryGetCachedValue(updatedKey) as OnyxValue<TKey>;
204212
const selectedValue = selectorRef.current ? selectorRef.current(value) : value;
205213
newValueRef.current = (selectedValue ?? undefined) as TReturnValue | undefined;
206214

@@ -213,15 +221,15 @@ function useOnyx<TKey extends OnyxKey, TReturnValue = OnyxValue<TKey>>(
213221
shouldGetCachedValueRef.current = false;
214222
}
215223

216-
const hasCacheForKey = OnyxCache.hasCacheForKey(key);
224+
const hasCacheForKey = OnyxCache.hasCacheForKey(updatedKey);
217225

218226
// Since the fetch status can be different given the use cases below, we define the variable right away.
219227
let newFetchStatus: FetchStatus | undefined;
220228

221229
// If we have pending merge operations for the key during the first connection, we set the new value to `undefined`
222230
// and fetch status to `loading` to simulate that it is still being loaded until we have the most updated data.
223231
// If `allowStaleData` is `true` this logic will be ignored and cached value will be used, even if it's stale data.
224-
if (isFirstConnectionRef.current && OnyxUtils.hasPendingMergeForKey(key) && !options?.allowStaleData) {
232+
if (isFirstConnectionRef.current && OnyxUtils.hasPendingMergeForKey(updatedKey) && !options?.allowStaleData) {
225233
newValueRef.current = undefined;
226234
newFetchStatus = 'loading';
227235
}
@@ -267,20 +275,20 @@ function useOnyx<TKey extends OnyxKey, TReturnValue = OnyxValue<TKey>>(
267275
// we log an alert so it can be acknowledged by the consumer. Additionally, we won't log alerts
268276
// if there's a `Onyx.clear()` task in progress.
269277
if (options?.canBeMissing === false && newStatus === 'loaded' && !isOnyxValueDefined && !OnyxCache.hasPendingTask(TASK.CLEAR)) {
270-
Logger.logAlert(`useOnyx returned no data for key with canBeMissing set to false for key ${key}`, {showAlert: true});
278+
Logger.logAlert(`useOnyx returned no data for key with canBeMissing set to false for key ${updatedKey}`, {showAlert: true});
271279
}
272280
}
273281

274282
return resultRef.current;
275-
}, [options?.initWithStoredValues, options?.allowStaleData, options?.initialValue, options?.canBeMissing, key, selectorRef]);
283+
}, [options?.initWithStoredValues, options?.allowStaleData, options?.initialValue, options?.canBeMissing, updatedKey, selectorRef]);
276284

277285
const subscribe = useCallback(
278286
(onStoreChange: () => void) => {
279287
isConnectingRef.current = true;
280288
onStoreChangeFnRef.current = onStoreChange;
281289

282290
connectionRef.current = connectionManager.connect<CollectionKeyBase>({
283-
key,
291+
key: updatedKey,
284292
callback: (value, callbackKey, sourceValue) => {
285293
isConnectingRef.current = false;
286294
onStoreChangeFnRef.current = onStoreChange;
@@ -299,7 +307,7 @@ function useOnyx<TKey extends OnyxKey, TReturnValue = OnyxValue<TKey>>(
299307
onStoreChange();
300308
},
301309
initWithStoredValues: options?.initWithStoredValues,
302-
waitForCollectionCallback: OnyxUtils.isCollectionKey(key) as true,
310+
waitForCollectionCallback: OnyxUtils.isCollectionKey(updatedKey) as true,
303311
reuseConnection: options?.reuseConnection,
304312
});
305313

@@ -316,7 +324,7 @@ function useOnyx<TKey extends OnyxKey, TReturnValue = OnyxValue<TKey>>(
316324
onStoreChangeFnRef.current = null;
317325
};
318326
},
319-
[key, options?.initWithStoredValues, options?.reuseConnection, checkEvictableKey],
327+
[updatedKey, options?.initWithStoredValues, options?.reuseConnection, checkEvictableKey],
320328
);
321329

322330
const getSnapshotDecorated = useMemo(() => {

0 commit comments

Comments
 (0)