Skip to content

Commit 05fb8da

Browse files
committed
feat: add useDebouncedCallback hook
1 parent a87dd3b commit 05fb8da

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

src/useDebouncedCallback.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { useCallback } from 'react'
2+
import useTimeout from './useTimeout'
3+
4+
/**
5+
* Creates a debounced function that will invoke the input function after the
6+
* specified delay.
7+
*
8+
* @param fn a function that will be debounced
9+
* @param delay The milliseconds delay before invoking the function
10+
*/
11+
export default function useDebouncedCallback<
12+
TCallback extends (...args: any[]) => any
13+
>(fn: TCallback, delay: number): TCallback {
14+
const timeout = useTimeout()
15+
return useCallback(
16+
(...args: any[]) => {
17+
timeout.set(() => {
18+
fn(...args)
19+
}, delay)
20+
},
21+
[fn, delay],
22+
) as any
23+
}

test/useDebouncedCallback.test.tsx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import React from 'react'
2+
import { mount } from 'enzyme'
3+
import useDebouncedCallback from '../src/useDebouncedCallback'
4+
5+
describe('useDebouncedCallback', () => {
6+
it('should return a function that debounces input callback', () => {
7+
jest.useFakeTimers()
8+
const spy = jest.fn()
9+
10+
let debouncedFn;
11+
12+
function Wrapper() {
13+
debouncedFn = useDebouncedCallback(spy, 500)
14+
return <span />
15+
}
16+
17+
mount(<Wrapper />)
18+
19+
debouncedFn(1)
20+
debouncedFn(2)
21+
debouncedFn(3)
22+
expect(spy).not.toHaveBeenCalled()
23+
24+
jest.runOnlyPendingTimers()
25+
26+
expect(spy).toHaveBeenCalledTimes(1)
27+
expect(spy).toHaveBeenCalledWith(3)
28+
})
29+
})

0 commit comments

Comments
 (0)