Skip to content

Commit

Permalink
feat: add useInterval hook
Browse files Browse the repository at this point in the history
  • Loading branch information
streamich authored Jul 16, 2019
2 parents 655e62e + 40b33da commit 6645ed9
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 3 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
<br/>
- [**Animations**](./docs/Animations.md)
- [`useRaf`](./docs/useRaf.md) &mdash; re-renders component on each `requestAnimationFrame`.
- [`useInterval`](./docs/useInterval.md) &mdash; re-renders component on a set interval using `setInterval`.
- [`useSpring`](./docs/useSpring.md) &mdash; interpolates number over time according to spring dynamics.
- [`useTimeout`](./docs/useTimeout.md) &mdash; returns true after a timeout.
- [`useTween`](./docs/useTween.md) &mdash; re-renders component, while tweening a number from 0 to 1. [![][img-demo]](https://codesandbox.io/s/52990wwzyl)
Expand Down
42 changes: 42 additions & 0 deletions docs/useInterval.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# `useInterval`

React hook that allow you using declarative `setInterval`.

## Usage

```jsx
import * as React from 'react';
import useInterval from 'react-use/lib/useInterval';

const Demo = () => {
const [count, setCount] = React.useState(0);
const [delay, setDelay] = React.useState(1000);

useInterval(() => {
setCount(count + 1);
}, delay);

function handleDelayChange(e) {
setDelay(Number(e.target.value));
}

return (
<div>
<div>
delay: <input value={delay} onChange={handleDelayChange} />
</div>
<h1>count: {count}</h1>
<div>
<button onClick={() => setDelay(delay ? null : 1000)}>{delay ? 'stop' : 'start'}</button>
</div>
</div>
);
};
```


## Reference

```js
useInterval(fn, delay?: number)
```
33 changes: 33 additions & 0 deletions src/__stories__/useInterval.story.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { storiesOf } from '@storybook/react';
import * as React from 'react';
import { useInterval } from '..';
import ShowDocs from './util/ShowDocs';

const Demo = () => {
const [count, setCount] = React.useState(0);
const [delay, setDelay] = React.useState(1000);

useInterval(() => {
setCount(count + 1);
}, delay);

function handleDelayChange(e) {
setDelay(Number(e.target.value));
}

return (
<div>
<div>
delay: <input value={delay} onChange={handleDelayChange} />
</div>
<h1>count: {count}</h1>
<div>
<button onClick={() => setDelay(delay ? null : 1000)}>{delay ? 'stop' : 'start'}</button>
</div>
</div>
);
};

storiesOf('Side effects|useInterval', module)
.add('Docs', () => <ShowDocs md={require('../../docs/useInterval.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 @@ -25,6 +25,7 @@ import useGetSetState from './useGetSetState';
import useHover from './useHover';
import useHoverDirty from './useHoverDirty';
import useIdle from './useIdle';
import useInterval from './useInterval';
import useIsomorphicLayoutEffect from './useIsomorphicLayoutEffect';
import useKey from './useKey';
import useKeyboardJs from './useKeyboardJs';
Expand Down Expand Up @@ -103,6 +104,7 @@ export {
useHover,
useHoverDirty,
useIdle,
useInterval,
useIsomorphicLayoutEffect,
useKey,
useKeyboardJs,
Expand Down
4 changes: 2 additions & 2 deletions src/useDebounce.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useEffect } from 'react';
import useUpdateEffect from './useUpdateEffect';

const useDebounce = (fn: () => any, ms: number = 0, args: any[] = []) => {
useEffect(() => {
useUpdateEffect(() => {
const handle = setTimeout(fn.bind(null, args), ms);

return () => {
Expand Down
19 changes: 19 additions & 0 deletions src/useInterval.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { useRef, useEffect } from 'react';

const useInterval = (callback: Function, delay?: number | null) => {
const latestCallback = useRef<Function>(() => {});

useEffect(() => {
latestCallback.current = callback;
});

useEffect(() => {
if (delay !== null) {
const interval = setInterval(() => latestCallback.current(), delay || 0);
return () => clearInterval(interval);
}
return undefined;
}, [delay]);
};

export default useInterval;
3 changes: 2 additions & 1 deletion tslint.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
"printWidth": 120,
"tabWidth": 2
}
]
],
"ordered-imports": false
},
"rulesDirectory": ["tslint-plugin-prettier"]
}

0 comments on commit 6645ed9

Please sign in to comment.