React Dojo

Search

Search concepts, exercises and quizzes

dom

useIdle

Detects when the user has been idle for a given amount of time (no mouse movement, keystrokes, or scrolling). Useful for screensavers, session timeouts, or pausing animations.


useIdle.ts
import { useState, useEffect, useCallback, useRef } from "react"

export function useIdle(timeout: number = 3000): boolean {
  const [isIdle, setIsIdle] = useState(false)
  const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null)

  const resetTimer = useCallback(() => {
    if (timerRef.current) clearTimeout(timerRef.current)
    setIsIdle(false)
    timerRef.current = setTimeout(() => setIsIdle(true), timeout)
  }, [timeout])

  useEffect(() => {
    const events = ["mousemove", "mousedown", "keydown", "touchstart", "scroll"]

    events.forEach((event) => window.addEventListener(event, resetTimer))
    resetTimer()

    return () => {
      if (timerRef.current) clearTimeout(timerRef.current)
      events.forEach((event) => window.removeEventListener(event, resetTimer))
    }
  }, [resetTimer])

  return isIdle
}
Was this helpful?
Sign in to give feedback