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.
Usage
import { useState } from 'react'
import type { ChangeEvent } from 'react'
import { useInterval } from './useInterval'
export default function Component() {
// The counter
const [count, setCount] = useState<number>(0)
// Dynamic delay
const [delay, setDelay] = useState<number>(1000)
// ON/OFF
const [isPlaying, setPlaying] = useState<boolean>(false)
useInterval(
() => {
// Your custom logic here
setCount(count + 1)
},
// Delay in milliseconds or null to stop it
isPlaying ? delay : null,
)
const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
setDelay(Number(event.target.value))
}
return (
<>
<h1>{count}</h1>
<button
onClick={() => {
setPlaying(!isPlaying)
}}
>
{isPlaying ? 'pause' : 'play'}
</button>
<p>
<label htmlFor="delay">Delay: </label>
<input type="number" name="delay" onChange={handleChange} value={delay} />
</p>
</>
)
}
API
function useInterval(callback: () => void, delay: number | null): void
Custom hook that creates an interval that invokes a callback function at a specified delay using the setInterval API.
Parameters
| Name | Type | Default value | Description |
|---|---|---|---|
callback | () => void | - | The function to be invoked at each interval. |
delay | `number | null` | - |
Returns
No return description available yet.
Hook
import { useEffect, useRef } from 'react'
import { useIsomorphicLayoutEffect } from '../useIsomorphicLayoutEffect'
/**
* Custom hook that creates an interval that invokes a callback function at a specified delay using the [`setInterval API`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval).
* @param {() => void} callback - The function to be invoked at each interval.
* @param {number | null} delay - The time, in milliseconds, between each invocation of the callback. Use `null` to clear the interval.
* @public
* @see [Documentation](https://usehooks-ts.com/react-hook/use-interval)
* @example
* ```tsx
* const handleInterval = () => {
* // Code to be executed at each interval
* };
* useInterval(handleInterval, 1000);
* ```
*/
export function useInterval(callback: () => void, delay: number | null) {
const savedCallback = useRef(callback)
// Remember the latest callback if it changes.
useIsomorphicLayoutEffect(() => {
savedCallback.current = callback
}, [callback])
// Set up the interval.
useEffect(() => {
// Don't schedule if no delay is specified.
// Note: 0 is a valid value for delay.
if (delay === null) {
return
}
const id = setInterval(() => {
savedCallback.current()
}, delay)
return () => {
clearInterval(id)
}
}, [delay])
}