From 8f2d60feb47e6823faf688dc45295475cae2c7a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Henriques?= Date: Tue, 24 Sep 2024 19:15:49 +0100 Subject: [PATCH] Fix useOnyx to don't use initialValue or selector if initWithStoredValues is false --- lib/useOnyx.ts | 9 +++++++-- tests/unit/useOnyxTest.ts | 16 ++++++++-------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/lib/useOnyx.ts b/lib/useOnyx.ts index 3abea163..0b26428f 100644 --- a/lib/useOnyx.ts +++ b/lib/useOnyx.ts @@ -85,7 +85,7 @@ function useOnyx>(key: TKey // Stores the previously result returned by the hook, containing the data from cache and the fetch status. // We initialize it to `undefined` and `loading` fetch status to simulate the initial result when the hook is loading from the cache. - // However, if `initWithStoredValues` is `true` we set the fetch status to `loaded` since we want to signal that data is ready. + // However, if `initWithStoredValues` is `false` we set the fetch status to `loaded` since we want to signal that data is ready. const resultRef = useRef>([ undefined as CachedValue, { @@ -146,6 +146,11 @@ function useOnyx>(key: TKey }, [key, options?.canEvict]); const getSnapshot = useCallback(() => { + // We return the initial result right away during the first connection if `initWithStoredValues` is set to `false`. + if (isFirstConnectionRef.current && options?.initWithStoredValues === false) { + return resultRef.current; + } + // We get the value from cache while the first connection to Onyx is being made, // so we can return any cached value right away. After the connection is made, we only // update `newValueRef` when `Onyx.connect()` callback is fired. @@ -203,7 +208,7 @@ function useOnyx>(key: TKey } return resultRef.current; - }, [key, selectorRef, options?.allowStaleData, options?.initialValue]); + }, [key, selectorRef, options?.initWithStoredValues, options?.allowStaleData, options?.initialValue]); const subscribe = useCallback( (onStoreChange: () => void) => { diff --git a/tests/unit/useOnyxTest.ts b/tests/unit/useOnyxTest.ts index 25b56631..cbd95d41 100644 --- a/tests/unit/useOnyxTest.ts +++ b/tests/unit/useOnyxTest.ts @@ -463,7 +463,7 @@ describe('useOnyx', () => { expect(result.current[1].status).toEqual('loaded'); }); - it('should return initial value and loaded state, and after merge return updated value and loaded state', async () => { + it('should return `undefined` and loaded state if using `initialValue`, and after merge return updated value and loaded state', async () => { await StorageMock.setItem(ONYXKEYS.TEST_KEY, 'test1'); const {result} = renderHook(() => @@ -475,16 +475,16 @@ describe('useOnyx', () => { await act(async () => waitForPromisesToResolve()); - expect(result.current[0]).toEqual('initial value'); + expect(result.current[0]).toBeUndefined(); expect(result.current[1].status).toEqual('loaded'); - await act(async () => Onyx.merge(ONYXKEYS.TEST_KEY, 'test2')); + await act(async () => Onyx.merge(ONYXKEYS.TEST_KEY, 'test')); - expect(result.current[0]).toEqual('test2'); + expect(result.current[0]).toEqual('test'); expect(result.current[1].status).toEqual('loaded'); }); - it('should return selected value and loaded state, and after merge return updated selected value and loaded state', async () => { + it('should return `undefined` value and loaded state if using `selector`, and after merge return selected value and loaded state', async () => { await StorageMock.setItem(ONYXKEYS.TEST_KEY, 'test1'); const {result} = renderHook(() => @@ -497,12 +497,12 @@ describe('useOnyx', () => { await act(async () => waitForPromisesToResolve()); - expect(result.current[0]).toEqual('undefined_selected'); + expect(result.current[0]).toBeUndefined(); expect(result.current[1].status).toEqual('loaded'); - await act(async () => Onyx.merge(ONYXKEYS.TEST_KEY, 'test2')); + await act(async () => Onyx.merge(ONYXKEYS.TEST_KEY, 'test')); - expect(result.current[0]).toEqual('test2_selected'); + expect(result.current[0]).toEqual('test_selected'); expect(result.current[1].status).toEqual('loaded'); }); });