useInterval()

Use setInterval in functional React component with the same API. Set your callback function as a first parameter and a delay (in milliseconds) for the second argument. You can also stop the timer passing null instead the delay or even, execute it right away passing 0.

The main difference between the setInterval you know and this useInterval hook is that its arguments are "dynamic". You can get more information in the Dan Abramov's blog post.

The Hook

1import { useEffect, useRef } from 'react'
2
3import { useIsomorphicLayoutEffect } from 'usehooks-ts'
4
5function useInterval(callback: () => void, delay: number | null) {
6 const savedCallback = useRef(callback)
7
8 // Remember the latest callback if it changes.
9 useIsomorphicLayoutEffect(() => {
10 savedCallback.current = callback
11 }, [callback])
12
13 // Set up the interval.
14 useEffect(() => {
15 // Don't schedule if no delay is specified.
16 // Note: 0 is a valid value for delay.
17 if (!delay && delay !== 0) {
18 return
19 }
20
21 const id = setInterval(() => savedCallback.current(), delay)
22
23 return () => clearInterval(id)
24 }, [delay])
25}
26
27export default useInterval

Usage

1import { ChangeEvent, useState } from 'react'
2
3import { useInterval } from 'usehooks-ts'
4
5export default function Component() {
6 // The counter
7 const [count, setCount] = useState<number>(0)
8 // Dynamic delay
9 const [delay, setDelay] = useState<number>(1000)
10 // ON/OFF
11 const [isPlaying, setPlaying] = useState<boolean>(false)
12
13 useInterval(
14 () => {
15 // Your custom logic here
16 setCount(count + 1)
17 },
18 // Delay in milliseconds or null to stop it
19 isPlaying ? delay : null,
20 )
21
22 const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
23 setDelay(Number(event.target.value))
24 }
25
26 return (
27 <>
28 <h1>{count}</h1>
29 <button onClick={() => setPlaying(!isPlaying)}>
30 {isPlaying ? 'pause' : 'play'}
31 </button>
32 <p>
33 <label htmlFor="delay">Delay: </label>
34 <input
35 type="number"
36 name="delay"
37 onChange={handleChange}
38 value={delay}
39 />
40 </p>
41 </>
42 )
43}

Edit on CodeSandbox

See a way to make this page better?
Edit there »