JAVASCRIPT
Manage Timed Actions with useInterval Hook
A safe and declarative React hook for handling `setInterval` logic, ensuring intervals are cleared properly and preventing common closure issues.
import { useEffect, useRef } from 'react';
const useInterval = (callback, delay) => {
const savedCallback = useRef();
// Remember the latest callback.
useEffect(() => {
savedCallback.current = callback;
}, [callback]);
// Set up the interval.
useEffect(() => {
function tick() {
savedCallback.current();
}
if (delay !== null) {
let id = setInterval(tick, delay);
return () => clearInterval(id);
}
}, [delay]);
};
// Example Usage:
// function Counter() {
// const [count, setCount] = useState(0);
// const [delay, setDelay] = useState(1000); // 1 second
// const [isRunning, setIsRunning] = useState(true);
//
// useInterval(
// () => {
// setCount(count + 1);
// },
// isRunning ? delay : null
// );
//
// const handleDelayChange = (e) => {
// setDelay(Number(e.target.value));
// };
//
// return (
// <div>
// <h1>Count: {count}</h1>
// <button onClick={() => setIsRunning(!isRunning)}>
// {isRunning ? 'Stop' : 'Start'}
// </button>
// <input type="number" value={delay} onChange={handleDelayChange} />
// <p>Delay: {delay}ms</p>
// </div>
// );
// }
How it works: The useInterval hook provides a robust way to manage `setInterval` in React components. It uses `useRef` to store the latest `callback` function, effectively preventing common stale closure issues. `useEffect` then establishes the interval, and critically, returns a cleanup function to clear the interval when the component unmounts or the `delay` changes, preventing memory leaks. Setting the `delay` to `null` can effectively pause the interval.