A lightweight, reusable React hook package that provides two battle-tested utilities: useTimeout
and useInterval
. These help you manage time-based side effects in React apps — cleanly and safely.
Fully React-idiomatic · Auto Cleanup · Functional-safe · Zero Dependencies
- Delay Execution (Timeout) — run code after a specified delay
- Repeat Execution (Interval) — run code at a set frequency
- No Memory Leaks — auto-clears timers on unmount
- Safe Callback Handling — avoids stale closures
- Manual Control — start, stop, reset methods
- Tiny and Efficient — no dependencies except React
npm install @mdus/use-timer-hooks # or yarn add @mdus/use-timer-hooks
Runs a function once after the given delay (in milliseconds).
Parameter | Type | Required | Description |
---|---|---|---|
callback | () => void | ✅ | Function to run once after delay |
delay | number | ✅ | Time in ms to wait before firing |
Key | Type | Description |
---|---|---|
startTimeout() | function | Start (or restart) the timeout |
stopTimeout() | function | Cancel the timeout |
resetTimeout() | function | Reset the timeout (stop + start) |
isTimeoutActive | boolean | True while the timeout is counting down |
- If
delay
is invalid (null
,false
, etc), nothing runs - Automatically stops on component unmount
- Callback is kept in sync (doesn't go stale)
Runs a function repeatedly at the given interval (in milliseconds).
Parameter | Type | Required | Description |
---|---|---|---|
callback | () => void | ✅ | Function to run on each interval |
delay | number | ✅ | Time between runs (in milliseconds) |
Key | Type | Description |
---|---|---|
startInterval() | function | Starts the interval |
stopInterval() | function | Stops the interval |
resetInterval() | function | Stops and restarts the interval |
isIntervalActive | boolean | True while the interval is running |
import { useTimeout } from "@mdus/use-timer-hooks"; function Message() { const [show, setShow] = useState(true); // Hide message after 3s useTimeout(() => setShow(false), 3000); return show ? <p>Hello! This disappears in 3 seconds.</p> : null; }
import { useInterval } from "@mdus/use-timer-hooks"; function Countdown() { const [seconds, setSeconds] = useState(10); const { stopInterval, isIntervalActive } = useInterval(() => { setSeconds((prev) => { if (prev <= 1) { stopInterval(); // Stop when we hit 0 return 0; } return prev - 1; }); }, 1000); return ( <p> Countdown: {seconds} {isIntervalActive ? "" : "(Done)"} </p> ); }
import { useTimeout } from "@mdus/use-timer-hooks"; function DebouncedSearch({ value, onSearch }) { const { resetTimeout } = useTimeout(() => { onSearch(value); }, 500); // debounce 500ms useEffect(() => { resetTimeout(); // re-trigger on value change }, [value]); return null; }
- We use
useRef
to store the latest version of your callback to prevent stale closure issues. - Both hooks automatically clear timers when the component unmounts — you don't need to worry about leaks or race conditions.
- Manual
startX()
,stopX()
, andresetX()
functions give you full control.
use-timer-hooks/ ├── src/ │ └── useTimer.js ├── dist/ │ └── index.js ├── package.json ├── README.md └── LICENSE
Md Umar Siddique
Frontend-first engineer building real-world tools with long-term value.
-
GitHub: @umarSiddique010
-
LinkedIn: md-umar-siddique
-
Twitter/X: @umarSiddique010
-
Dev.to: @umarSiddique010
Pull requests are welcome! If you'd like to improve anything or need another timing hook, open an issue or PR.
MIT License — use freely, credit appreciated.