JAVASCRIPT
React Hook: useTimeout for Delaying Actions with Automatic Cleanup
Implement time-delayed actions in React components with `useTimeout`. This hook manages `setTimeout` with automatic cleanup on unmount or dependency change, preventing memory leaks.
import { useRef, useEffect, useCallback } => 'react';
function useTimeout(callback, delay) {
const callbackRef = useRef(callback);
const timeoutRef = useRef();
// Update callbackRef when callback changes
useEffect(() => {
callbackRef.current = callback;
}, [callback]);
// Set up the timeout
useEffect(() => {
if (typeof delay !== 'number' || delay < 0) {
return undefined;
}
timeoutRef.current = setTimeout(() => callbackRef.current(), delay);
// Cleanup on unmount or delay/callback change
return () => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
};
}, [delay]); // Only re-run if delay changes (callback is handled by callbackRef)
// Optional: A way to manually clear the timeout if needed
const clear = useCallback(() => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
timeoutRef.current = undefined;
}
}, []);
return clear;
}
How it works: The `useTimeout` hook provides a safe way to use `setTimeout` in React. It stores the provided `callback` in a `useRef` (so it doesn't trigger `useEffect` re-runs if it changes, only the `delay` does). The main `useEffect` sets up the `setTimeout` and returns a cleanup function that calls `clearTimeout`. This ensures that the timeout is automatically cleared if the component unmounts, or if the `delay` value changes, preventing memory leaks and unwanted side effects. It also returns an optional `clear` function to manually cancel the timeout.