Skip to content

Commit

Permalink
feat: added useDebounce
Browse files Browse the repository at this point in the history
  • Loading branch information
Jivings committed Dec 18, 2018
1 parent 3c9a48e commit 91ff6ba
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 0 deletions.
46 changes: 46 additions & 0 deletions docs/useDebounce.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# `useDebounce`

React hook that delays invoking a function until after wait milliseconds have elapsed since the last time the debounced function was invoked.

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.

## Usage

```jsx
import React, { useState } from 'react';
import { useDebounce } from 'react-use';

const Demo = () => {
const [state, setState] = React.useState('Typing stopped');
const [val, setVal] = React.useState('');

useDebounce(
() => {
setState('Typing stopped');
},
2000,
[val]
);

return (
<div>
<input
type="text"
value={val}
placeholder="Debounced input"
onChange={({ currentTarget }) => {
setState('Waiting for typing to stop...');
setVal(currentTarget.value);
}}
/>
<div>{state}</div>
</div>
);
};
```

## Reference

```ts
useDebouce(fn, ms: number, args: any[]);
```
36 changes: 36 additions & 0 deletions src/__stories__/useDebounce.story.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import * as React from 'react';
import { storiesOf } from '@storybook/react';
import { useDebounce } from '..';
import ShowDocs from '../util/ShowDocs';

const Demo = () => {
const [state, setState] = React.useState('Typing stopped');
const [val, setVal] = React.useState('');

useDebounce(
() => {
setState('Typing stopped');
},
2000,
[val]
);

return (
<div>
<input
type="text"
value={val}
placeholder="Debounced input"
onChange={({ currentTarget }) => {
setState('Waiting for typing to stop...');
setVal(currentTarget.value);
}}
/>
<div>{state}</div>
</div>
);
};

storiesOf('Side effects/useDebounce', module)
.add('Docs', () => <ShowDocs md={require('../../docs/useDebounce.md')} />)
.add('Demo', () => <Demo />);
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import useBoolean from './useBoolean';
import useCallbag from './useCallbag';
import useCounter from './useCounter';
import useCss from './useCss';
import useDebounce from './useDebounce';
import useFavicon from './useFavicon';
import useGeolocation from './useGeolocation';
import useGetSet from './useGetSet';
Expand Down Expand Up @@ -54,6 +55,7 @@ export {
useCallbag,
useCounter,
useCss,
useDebounce,
useFavicon,
useGeolocation,
useGetSet,
Expand Down
14 changes: 14 additions & 0 deletions src/useDebounce.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { useState, useEffect } from 'react';

const useDebounce = (fn: () => any, ms: number = 0, args: Array<any> = []) => {
const [timeout, setTimeoutVar] = useState<number>(-1);

useEffect(() => {
// if args change then clear timeout
clearTimeout(timeout);
const t = setTimeout(fn.bind(null, args), ms);
setTimeoutVar(t);
}, args);
};

export default useDebounce;

0 comments on commit 91ff6ba

Please sign in to comment.