diff --git a/lib/useOnyx.ts b/lib/useOnyx.ts index be7521048..0ce1a4a63 100644 --- a/lib/useOnyx.ts +++ b/lib/useOnyx.ts @@ -112,6 +112,10 @@ function useOnyx>( // explicit reset logic — eliminating the race condition where cleanup could clobber a boolean flag. const connectedKeyRef = useRef(null); + // Tracks whether the hook has completed its initial mount subscription. + // Unlike connectedKeyRef (which gets nulled by cleanup), this persists across re-subscriptions. + const hasMountedRef = useRef(false); + // Indicates if the hook is connecting to an Onyx key. const isConnectingRef = useRef(false); @@ -264,12 +268,19 @@ function useOnyx>( (onStoreChange: () => void) => { // Reset internal state so the hook properly transitions through loading // for the new key instead of preserving stale state from the previous one. - previousValueRef.current = null; - newValueRef.current = null; + // Only reset when the key has actually changed (not on initial mount). + if (hasMountedRef.current) { + previousValueRef.current = null; + newValueRef.current = null; + sourceValueRef.current = undefined; + resultRef.current = [undefined, {status: options?.initWithStoredValues === false ? 'loaded' : 'loading'}]; + } + // Force a cache re-read on every (re)subscription so any side effects from + // subscribeToKey (e.g. addNullishStorageKey for skippable collection member ids) + // are reflected in the next getSnapshot. Resetting this flag does not change + // resultRef by itself, so it doesn't cause an extra mount render. shouldGetCachedValueRef.current = true; - sourceValueRef.current = undefined; - resultRef.current = [undefined, {status: options?.initWithStoredValues === false ? 'loaded' : 'loading'}]; - + hasMountedRef.current = true; isConnectingRef.current = true; onStoreChangeFnRef.current = onStoreChange;