Skip to content

Commit 06f63ea

Browse files
committed
add isSkippableKey to avoid recalculations
1 parent 218c1cd commit 06f63ea

1 file changed

Lines changed: 25 additions & 17 deletions

File tree

lib/useOnyx.ts

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,21 @@ function useOnyx<TKey extends OnyxKey, TReturnValue = OnyxValue<TKey>>(
163163

164164
useEffect(() => () => onyxSnapshotCache.deregisterConsumer(key, cacheKey), [key, cacheKey]);
165165

166+
// Precompute whether this key is a skippable collection member so that getSnapshot()
167+
// can use a cheap boolean check instead of calling splitCollectionMemberKey on every render.
168+
const isSkippableKey = useMemo(() => {
169+
const skippableIDs = OnyxUtils.getSkippableCollectionMemberIDs();
170+
if (!skippableIDs.size) {
171+
return false;
172+
}
173+
try {
174+
const [, memberId] = OnyxUtils.splitCollectionMemberKey(key);
175+
return skippableIDs.has(memberId);
176+
} catch {
177+
return false;
178+
}
179+
}, [key]);
180+
166181
useEffect(() => {
167182
// These conditions will ensure we can only handle dynamic collection member keys from the same collection.
168183
if (options?.allowDynamicKey || previousKey === key) {
@@ -231,23 +246,16 @@ function useOnyx<TKey extends OnyxKey, TReturnValue = OnyxValue<TKey>>(
231246
}, [key, options?.canEvict]);
232247

233248
const getSnapshot = useCallback(() => {
234-
// Fast path: if subscribing to a skippable collection member id, return undefined as loaded immediately
235-
if (isFirstConnectionRef.current) {
236-
try {
237-
const [, memberId] = OnyxUtils.splitCollectionMemberKey(key);
238-
if (OnyxUtils.getSkippableCollectionMemberIDs().has(memberId)) {
239-
// Finalize initial state as loaded undefined and stop further first-connection flows
240-
if (resultRef.current[1].status !== 'loaded' || resultRef.current[0] !== undefined) {
241-
resultRef.current = [undefined, {status: 'loaded'}];
242-
onyxSnapshotCache.setCachedResult<UseOnyxResult<TReturnValue>>(key, cacheKey, resultRef.current);
243-
}
244-
isFirstConnectionRef.current = false;
245-
shouldGetCachedValueRef.current = false;
246-
return resultRef.current;
247-
}
248-
} catch (e) {
249-
// Not a collection member, continue as usual
249+
// Fast path: if subscribing to a skippable collection member id, return undefined as loaded immediately.
250+
// The `isSkippableKey` flag is precomputed so we avoid calling splitCollectionMemberKey here.
251+
if (isFirstConnectionRef.current && isSkippableKey) {
252+
if (resultRef.current[1].status !== 'loaded' || resultRef.current[0] !== undefined) {
253+
resultRef.current = [undefined, {status: 'loaded'}];
254+
onyxSnapshotCache.setCachedResult<UseOnyxResult<TReturnValue>>(key, cacheKey, resultRef.current);
250255
}
256+
isFirstConnectionRef.current = false;
257+
shouldGetCachedValueRef.current = false;
258+
return resultRef.current;
251259
}
252260
// Check if we have any cache for this Onyx key
253261
// Don't use cache for first connection with initWithStoredValues: false
@@ -349,7 +357,7 @@ function useOnyx<TKey extends OnyxKey, TReturnValue = OnyxValue<TKey>>(
349357
}
350358

351359
return resultRef.current;
352-
}, [options?.initWithStoredValues, options?.allowStaleData, options?.canBeMissing, key, memoizedSelector, cacheKey, previousKey]);
360+
}, [options?.initWithStoredValues, options?.allowStaleData, options?.canBeMissing, key, memoizedSelector, cacheKey, previousKey, isSkippableKey]);
353361

354362
const subscribe = useCallback(
355363
(onStoreChange: () => void) => {

0 commit comments

Comments
 (0)