From 9cbde2e4a1cc962e788a2d762fcae5f19da51949 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Thu, 16 Jan 2025 13:03:59 +0700 Subject: [PATCH 1/2] Add param to allow dynamic key --- lib/useOnyx.ts | 9 +++++++-- tests/unit/useOnyxTest.ts | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/lib/useOnyx.ts b/lib/useOnyx.ts index 4a0860d3..001b54e2 100644 --- a/lib/useOnyx.ts +++ b/lib/useOnyx.ts @@ -32,6 +32,11 @@ type BaseUseOnyxOptions = { * with the same connect configurations. */ reuseConnection?: boolean; + + /** + * If set to `true`, the key can be changed dynamically during the component lifecycle. + */ + allowDynamicKey?: boolean; }; type UseOnyxInitialValueOption = { @@ -157,7 +162,7 @@ function useOnyx>( useEffect(() => { // These conditions will ensure we can only handle dynamic collection member keys from the same collection. - if (previousKey === key) { + if (options?.allowDynamicKey || previousKey === key) { return; } @@ -181,7 +186,7 @@ function useOnyx>( throw new Error( `'${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'.`, ); - }, [previousKey, key]); + }, [previousKey, key, options?.allowDynamicKey]); useEffect(() => { // This effect will only run if the `dependencies` array changes. If it changes it will force the hook diff --git a/tests/unit/useOnyxTest.ts b/tests/unit/useOnyxTest.ts index 2c874469..4efe5a2c 100644 --- a/tests/unit/useOnyxTest.ts +++ b/tests/unit/useOnyxTest.ts @@ -89,6 +89,44 @@ describe('useOnyx', () => { fail("Expected to don't throw any errors."); } }); + + it('should not throw an error when changing from a non-collection key to another one if allowDynamicKey is true', async () => { + const {rerender} = renderHook((key: string) => useOnyx(key, {allowDynamicKey: true}), {initialProps: ONYXKEYS.TEST_KEY}); + + try { + await act(async () => { + rerender(ONYXKEYS.TEST_KEY_2); + }); + } catch (e) { + fail("Expected to don't throw any errors."); + } + }); + + it('should throw an error when changing from a non-collection key to another one if allowDynamicKey is false', async () => { + const {rerender} = renderHook((key: string) => useOnyx(key, {allowDynamicKey: false}), {initialProps: ONYXKEYS.TEST_KEY}); + + try { + await act(async () => { + rerender(ONYXKEYS.TEST_KEY_2); + }); + + fail('Expected to throw an error.'); + } catch (e) { + expect((e as Error).message).toBe(error(ONYXKEYS.TEST_KEY, ONYXKEYS.TEST_KEY_2)); + } + }); + + it('should not throw an error when changing from a collection member key to another one if allowDynamicKey is true', async () => { + const {rerender} = renderHook((key: string) => useOnyx(key, {allowDynamicKey: true}), {initialProps: `${ONYXKEYS.COLLECTION.TEST_KEY}` as string}); + + try { + await act(async () => { + rerender(`${ONYXKEYS.COLLECTION.TEST_KEY_2}`); + }); + } catch (e) { + fail("Expected to don't throw any errors."); + } + }); }); describe('misc', () => { From f2cc869ac90a3d61f2b1a84d2179c0dd7a2f0c6d Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Thu, 16 Jan 2025 14:38:38 +0700 Subject: [PATCH 2/2] export required type to create the wrapper for snapshot --- lib/useOnyx.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/useOnyx.ts b/lib/useOnyx.ts index 001b54e2..2e2dc2ae 100644 --- a/lib/useOnyx.ts +++ b/lib/useOnyx.ts @@ -347,4 +347,4 @@ function useOnyx>( export default useOnyx; -export type {FetchStatus, ResultMetadata, UseOnyxResult}; +export type {FetchStatus, ResultMetadata, UseOnyxResult, BaseUseOnyxOptions, UseOnyxSelector, UseOnyxSelectorOption, UseOnyxInitialValueOption, UseOnyxOptions};