Skip to content

Commit 62d25cb

Browse files
committed
πŸ› Fix bug in useDebouncedCallback doesn't consider its dependencies (antonioru#420)
πŸ› Fix bug in useDebouncedCallback where dependencies were not considered (antonioru#420)
1 parent 420a676 commit 62d25cb

File tree

2 files changed

+36
-3
lines changed

2 files changed

+36
-3
lines changed

β€Žsrc/useDebouncedCallback.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,18 @@ const defaultOptions: DebounceOptions = {
2020
* If time is not defined, its default value will be 250ms.
2121
*/
2222
const useDebouncedCallback = <TCallback extends GenericFunction>
23-
(fn: TCallback, dependencies?: DependencyList, wait: number = 600, options: DebounceOptions = defaultOptions) => {
23+
(fn: TCallback, dependencies: DependencyList = [], wait: number = 600, options: DebounceOptions = defaultOptions) => {
2424
const debounced = useRef(debounce<TCallback>(fn, wait, options))
2525

2626
useEffect(() => {
2727
debounced.current = debounce(fn, wait, options)
28-
}, [fn, wait, options])
28+
}, [fn, wait, options, ...dependencies])
2929

3030
useWillUnmount(() => {
3131
debounced.current?.cancel()
3232
})
3333

34-
return useCallback(debounced.current, dependencies ?? [])
34+
return useCallback((...args: Parameters<TCallback>) => debounced.current(...args), [...dependencies])
3535
}
3636

3737
export default useDebouncedCallback

β€Žtest/useDebouncedCallback.spec.js

+33
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,37 @@ describe('useDebouncedCallback', () => {
4747
expect(spy.called).to.be.true
4848
expect(spy.callCount).to.equal(1)
4949
})
50+
51+
it('should use the latest callback', async () => {
52+
const firstSpy = sinon.spy();
53+
const secondSpy = sinon.spy();
54+
55+
const TestComponent = () => {
56+
const [callback, setCallback] = React.useState(() => firstSpy);
57+
const debouncedCallback = useDebouncedCallback(callback, [callback], 250);
58+
59+
React.useEffect(() => {
60+
debouncedCallback();
61+
debouncedCallback();
62+
63+
setTimeout(() => {
64+
setCallback(() => secondSpy);
65+
}, 100);
66+
67+
setTimeout(() => {
68+
debouncedCallback();
69+
debouncedCallback();
70+
}, 200);
71+
}, [debouncedCallback]);
72+
73+
return <div />;
74+
};
75+
76+
render(<TestComponent />);
77+
78+
await promiseDelay(600);
79+
80+
expect(firstSpy.callCount).to.equal(1);
81+
expect(secondSpy.callCount).to.equal(1);
82+
})
5083
})

0 commit comments

Comments
Β (0)