All hooks / Timers

useInterval

243 B minified and brotliedSourceMarkdown✓ Works in all modern browsers

Calls callback every delayMs milliseconds. Pass null as the delay to pause. Always calls the latest callback, so it can read current state without restarting the timer.

The timer restarts only when delayMs changes or it is paused and resumed. Browsers slow timers in background tabs (to once a second or less), so don't count ticks to measure time; compare Date.now() or use useNow. Cleared on unmount. Nothing runs on the server.

Import

import { useInterval } from '@vincent.ri/react-tils'
// or only this hook
import { useInterval } from '@vincent.ri/react-tils/useInterval'

Usage

const [count, setCount] = useState(0)
useInterval(() => setCount(count + 1), running ? 1000 : null)

// Poll every 5s, but not while the tab is in the background.
useInterval(refresh, 5000, { pauseWhenHidden: true })

Live demo

Ticks every 500ms; pauses in background tabs.

0 ticks

When to use it

Polling an API, a countdown or clock, or rotating a carousel.

When not to

You need a single delay; use setTimeout in an event handler or effect. For animation, use CSS or requestAnimationFrame. Server data that changes often may suit a data-fetching library with built-in refetching.

API

function useInterval(callback: () => void, delayMs: number | null, options?: IntervalOptions): void
ParameterDescription
callbackCalled on every tick. Can change every render.
delayMsMilliseconds between ticks, or null to pause.
optionspauseWhenHidden. Optional.

Types

export type IntervalOptions = {
  /** Pause while the tab is hidden, and resume when it is visible again. Default `false`. */
  pauseWhenHidden?: boolean;
};

Browser support

UsesChromeEdgeFirefoxSafariChrome AndroidSafari iOS
Page VisibilityWidely available33+12+18+7+33+7+

First version with support, from MDN's compatibility data (web-features 3.42.0, @mdn/browser-compat-data 8.1.5).