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.
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 { useRef, useEffect } from 'react'23function useInterval(callback: () => void, delay: number | null) {4 const savedCallback = useRef(callback)56 // Remember the latest callback if it changes.7 useEffect(() => {8 savedCallback.current = callback9 }, [callback])1011 // Set up the interval.12 useEffect(() => {13 // Don't schedule if no delay is specified.14 if (delay === null) {15 return16 }1718 const id = setInterval(() => savedCallback.current(), delay)1920 return () => clearInterval(id)21 }, [delay])22}2324export default useInterval
Usage
1import React, { useState, ChangeEvent } from 'react'23import useInterval from './useInterval'45export default function Component() {6 // The counter7 const [count, setCount] = useState<number>(0)8 // Dynamic delay9 const [delay, setDelay] = useState<number>(1000)10 // ON/OFF11 const [isPlaying, setPlaying] = useState<boolean>(false)1213 useInterval(14 () => {15 // Your custom logic here16 setCount(count + 1)17 },18 // Delay in milliseconds or null to stop it19 isPlaying ? delay : null,20 )2122 const handleChange = (event: ChangeEvent<HTMLInputElement>) => {23 setDelay(Number(event.target.value))24 }2526 return (27 <>28 <h1>{count}</h1>29 <button onClick={() => setPlaying(!isPlaying)}>30 {isPlaying ? 'pause' : 'play'}31 </button>32 <p>33 <label>Delay: </label>34 <input type="number" onChange={handleChange} value={delay} />35 </p>36 </>37 )38}
Created:
11 months ago