Skip to content

Commit ce8ae85

Browse files
committed
recompute selector when dependency change
1 parent c24b235 commit ce8ae85

1 file changed

Lines changed: 18 additions & 5 deletions

File tree

lib/useOnyx.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,30 +75,43 @@ function useOnyx<TKey extends OnyxKey, TReturnValue = OnyxValue<TKey>>(
7575
const connectionRef = useRef<Connection | null>(null);
7676
const previousKey = usePrevious(key);
7777

78+
const currentDependenciesRef = useRef(dependencies);
79+
currentDependenciesRef.current = dependencies;
80+
81+
const currentSelectorRef = useRef(options?.selector);
82+
currentSelectorRef.current = options?.selector;
83+
7884
// Create memoized version of selector for performance
7985
const memoizedSelector = useMemo(() => {
8086
if (!options?.selector) return null;
8187

8288
let lastInput: OnyxValue<TKey> | undefined;
8389
let lastOutput: TReturnValue;
90+
let lastDependencies: DependencyList = [];
8491
let hasComputed = false;
8592

8693
return (input: OnyxValue<TKey> | undefined): TReturnValue => {
87-
// Always recompute when input changes
88-
if (!hasComputed || lastInput !== input) {
89-
const newOutput = options.selector!(input);
94+
const currentDependencies = currentDependenciesRef.current;
95+
const currentSelector = currentSelectorRef.current;
96+
97+
// Recompute if input changed, dependencies changed, or first time
98+
const dependenciesChanged = !deepEqual(lastDependencies, currentDependencies);
99+
if (!hasComputed || lastInput !== input || dependenciesChanged) {
100+
const newOutput = currentSelector!(input);
90101

91102
// Deep equality mode: only update if output actually changed
92-
if (!hasComputed || !deepEqual(lastOutput, newOutput)) {
103+
if (!hasComputed || !deepEqual(lastOutput, newOutput) || dependenciesChanged) {
93104
lastInput = input;
94105
lastOutput = newOutput;
106+
lastDependencies = [...currentDependencies];
95107
hasComputed = true;
96108
}
97109
}
98110

99111
return lastOutput;
100112
};
101-
}, [options?.selector]);
113+
// eslint-disable-next-line react-hooks/exhaustive-deps
114+
}, [options?.selector, ...dependencies]);
102115

103116
// Stores the previous cached value as it's necessary to compare with the new value in `getSnapshot()`.
104117
// We initialize it to `null` to simulate that we don't have any value from cache yet.

0 commit comments

Comments
 (0)