Skip to content

Commit 91ff6ba

Browse files
committed
feat: added useDebounce
1 parent 3c9a48e commit 91ff6ba

File tree

4 files changed

+98
-0
lines changed

4 files changed

+98
-0
lines changed

docs/useDebounce.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# `useDebounce`
2+
3+
React hook that delays invoking a function until after wait milliseconds have elapsed since the last time the debounced function was invoked.
4+
5+
The third argument is the array of values that the debounce depends on, in the same manner as useEffect. The debounce timeout will start when one of the values changes.
6+
7+
## Usage
8+
9+
```jsx
10+
import React, { useState } from 'react';
11+
import { useDebounce } from 'react-use';
12+
13+
const Demo = () => {
14+
const [state, setState] = React.useState('Typing stopped');
15+
const [val, setVal] = React.useState('');
16+
17+
useDebounce(
18+
() => {
19+
setState('Typing stopped');
20+
},
21+
2000,
22+
[val]
23+
);
24+
25+
return (
26+
<div>
27+
<input
28+
type="text"
29+
value={val}
30+
placeholder="Debounced input"
31+
onChange={({ currentTarget }) => {
32+
setState('Waiting for typing to stop...');
33+
setVal(currentTarget.value);
34+
}}
35+
/>
36+
<div>{state}</div>
37+
</div>
38+
);
39+
};
40+
```
41+
42+
## Reference
43+
44+
```ts
45+
useDebouce(fn, ms: number, args: any[]);
46+
```

src/__stories__/useDebounce.story.tsx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import * as React from 'react';
2+
import { storiesOf } from '@storybook/react';
3+
import { useDebounce } from '..';
4+
import ShowDocs from '../util/ShowDocs';
5+
6+
const Demo = () => {
7+
const [state, setState] = React.useState('Typing stopped');
8+
const [val, setVal] = React.useState('');
9+
10+
useDebounce(
11+
() => {
12+
setState('Typing stopped');
13+
},
14+
2000,
15+
[val]
16+
);
17+
18+
return (
19+
<div>
20+
<input
21+
type="text"
22+
value={val}
23+
placeholder="Debounced input"
24+
onChange={({ currentTarget }) => {
25+
setState('Waiting for typing to stop...');
26+
setVal(currentTarget.value);
27+
}}
28+
/>
29+
<div>{state}</div>
30+
</div>
31+
);
32+
};
33+
34+
storiesOf('Side effects/useDebounce', module)
35+
.add('Docs', () => <ShowDocs md={require('../../docs/useDebounce.md')} />)
36+
.add('Demo', () => <Demo />);

src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import useBoolean from './useBoolean';
66
import useCallbag from './useCallbag';
77
import useCounter from './useCounter';
88
import useCss from './useCss';
9+
import useDebounce from './useDebounce';
910
import useFavicon from './useFavicon';
1011
import useGeolocation from './useGeolocation';
1112
import useGetSet from './useGetSet';
@@ -54,6 +55,7 @@ export {
5455
useCallbag,
5556
useCounter,
5657
useCss,
58+
useDebounce,
5759
useFavicon,
5860
useGeolocation,
5961
useGetSet,

src/useDebounce.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { useState, useEffect } from 'react';
2+
3+
const useDebounce = (fn: () => any, ms: number = 0, args: Array<any> = []) => {
4+
const [timeout, setTimeoutVar] = useState<number>(-1);
5+
6+
useEffect(() => {
7+
// if args change then clear timeout
8+
clearTimeout(timeout);
9+
const t = setTimeout(fn.bind(null, args), ms);
10+
setTimeoutVar(t);
11+
}, args);
12+
};
13+
14+
export default useDebounce;

0 commit comments

Comments
 (0)