shadcn.io is an independent project built on shadcn/ui
useInterval runs your callback every few milliseconds, and stops when you pass null.
Pass a number to start and null to pause. The callback is kept in a ref, so it sees the latest state each tick. When you need to know the component is still on the page before you set state, use useIsMounted. In React the timer is started in an effect, so nothing ticks during server render.
Installation
Anatomy

Usage
import { useInterval } from "@/hooks/use-interval";useInterval(() => {
setCount((count) => count + 1);
}, running ? 1000 : null);Pass null while the timer should sit still. A number is the gap in milliseconds. Changing that number clears the old timer and starts a new wait.
FAQ
How do I pause and resume useInterval?
Pass null as the delay to pause, and pass a number of milliseconds to run. The effect clears the previous timer whenever the delay changes, including when it becomes null. Put the delay in state and set it to null from a button if you want a pause control. Passing the same number again after null starts a fresh interval, and the next tick waits one full delay.
Does the callback see the latest state?
Yes. Each render stores the callback you passed in a ref, and the interval calls that ref. The function that actually runs is the one from the latest render, so it sees current props and state. You do not need to list those values in a dependency array of this hook. The interval itself is only recreated when the delay changes, not when the callback identity changes.
What happens when I change the delay?
The effect cleans up the old timer and, if the new delay is a number, starts another. Timing resets. The next tick is one full delay after the change, not the remainder of the previous wait. Use that when a control switches between speeds. A delay of null clears the timer and does not start a new one. The callback you passed is left as it is.
Do I have to clear the interval myself?
No. The hook calls clearInterval when the component unmounts and whenever the delay changes. You do not get an id back, and the hook returns nothing. If you need the timer to stop while the component stays mounted, pass null. Starting it again is just passing a number. There is no separate stop function to call.
Is useInterval safe during server rendering?
Yes. setInterval runs inside an effect, so the server never starts a timer and the callback does not run during the server render. The first ticks happen after the client mounts. Passing null on the first render keeps it idle until you set a delay. That is the right setup for a demo or a counter that should not run on its own.
Does the callback run immediately, or after the delay?
It runs after the delay. The hook uses setInterval, which waits one full period before the first call, then repeats. It does not fire once on mount the way a manual call plus an interval would. If you need a tick right away, call the function yourself and also pass it to the hook. Changing the delay restarts that wait from zero.
API Reference
Parameters
callback() => void
Called on every tick.
- Type
() => void
delaynumber | null
Milliseconds between ticks. null pauses it; a new delay restarts the interval.
- Type
number | null











