diff --git a/lib/useLiveRef.ts b/lib/useLiveRef.ts index fb4bef295..869f439db 100644 --- a/lib/useLiveRef.ts +++ b/lib/useLiveRef.ts @@ -3,6 +3,9 @@ import {useRef} from 'react'; /** * Creates a mutable reference to a value, useful when you need to * maintain a reference to a value that may change over time without triggering re-renders. + * + * @deprecated This hook breaks the Rules of React, and should not be used. + * The migration effort to remove it safely is not currently planned. */ function useLiveRef(value: T) { const ref = useRef(value); diff --git a/lib/useOnyx.ts b/lib/useOnyx.ts index 016eb0f33..f2aa7fa49 100644 --- a/lib/useOnyx.ts +++ b/lib/useOnyx.ts @@ -78,11 +78,13 @@ function useOnyx>( const previousKey = usePrevious(key); const currentDependenciesRef = useLiveRef(dependencies); - const currentSelectorRef = useLiveRef(options?.selector); + const selector = options?.selector; // Create memoized version of selector for performance const memoizedSelector = useMemo(() => { - if (!options?.selector) return null; + if (!selector) { + return null; + } let lastInput: OnyxValue | undefined; let lastOutput: TReturnValue; @@ -91,14 +93,13 @@ function useOnyx>( return (input: OnyxValue | undefined): TReturnValue => { const currentDependencies = currentDependenciesRef.current; - const currentSelector = currentSelectorRef.current; // Recompute if input changed, dependencies changed, or first time const dependenciesChanged = !shallowEqual(lastDependencies, currentDependencies); if (!hasComputed || lastInput !== input || dependenciesChanged) { // Only proceed if we have a valid selector - if (currentSelector) { - const newOutput = currentSelector(input); + if (selector) { + const newOutput = selector(input); // Deep equality mode: only update if output actually changed if (!hasComputed || !deepEqual(lastOutput, newOutput) || dependenciesChanged) { @@ -112,7 +113,7 @@ function useOnyx>( return lastOutput; }; - }, [currentDependenciesRef, currentSelectorRef, options?.selector]); + }, [currentDependenciesRef, selector]); // Stores the previous cached value as it's necessary to compare with the new value in `getSnapshot()`. // We initialize it to `null` to simulate that we don't have any value from cache yet. diff --git a/tests/unit/useOnyxTest.ts b/tests/unit/useOnyxTest.ts index afaa6d66f..1438f5b08 100644 --- a/tests/unit/useOnyxTest.ts +++ b/tests/unit/useOnyxTest.ts @@ -409,7 +409,6 @@ describe('useOnyx', () => { expect(result.current[1].status).toEqual('loaded'); selector = (entry: OnyxEntry<{id: string; name: string}>) => `id - ${entry?.id}, name - ${entry?.name} - selector changed`; - // In a react app we expect the selector ref to change during a rerender (see selectorRef/useLiveRef) rerender(undefined); expect(result.current[0]).toEqual('id - test_id, name - test_name - selector changed');