Ghribi Ouassim

useInterval

Component 12

About

Execute a callback function at specified intervals with useInterval, supporting dynamic delays and cleanup on unmount.

Built with React and Tailwind. Copy the prompt and paste it into Claude Code, Cursor or Lovable: your agent adds useInterval to your project and fits it to your theme.

Code

How useInterval is used: the demo's code. The component's own source comes with a free account.

Usage.tsx

'use client'

import { useInterval } from "@/components/hooks/use-interval"
import { Button } from "@/components/ui/button"
import { Card } from "@/components/ui/card"
import { Slider } from "@/components/ui/slider"
import { useState } from "react"
import { Play, Pause, Timer, RotateCw } from "lucide-react"

export function UseIntervalDemo() {
  const [count, setCount] = useState<number>(0)
  const [delay, setDelay] = useState<number>(1000)
  const [isPlaying, setPlaying] = useState<boolean>(false)

  useInterval(
    () => {
      setCount(count + 1)
    },
    isPlaying ? delay : null
  )

  return (
    <div className="grid grid-cols-2 gap-6 max-w-4xl mx-auto">
      {/* Left Column - Interactive Demo */}
      <Card className="p-6">
        <div className="space-y-6">
          <div className="space-y-2">
            <h3 className="text-lg font-medium">Interval Counter</h3>
            <p className="text-sm text-muted-foreground">
              A counter that increments based on the interval
            </p>
          </div>

          <div className="flex flex-col items-center space-y-4">
            {/* Counter Display */}
            <div className="text-6xl font-bold tabular-nums">
              {count}
            </div>

            {/* Controls */}
            <div className="flex gap-2">
              <Button
                variant="outline"
                size="icon"
                onClick={() => setPlaying(!isPlaying)}
              >
                {isPlaying ? (
                  <Pause className="h-4 w-4" />
                ) : (
                  <Play className="h-4 w-4" />
                )}
              </Button>
              <Button
                variant="outline"
                size="icon"
                onClick={() => setCount(0)}
              >
                <RotateCw className="h-4 w-4" />
              </Button>
            </div>
          </div>

          <div className="space-y-3">
            <div className="flex items-center justify-between text-sm">
              <div className="flex items-center gap-2">
                <Timer className="h-4 w-4" />
                <span>Interval Delay:</span>
              </div>
              <span className="font-mono">{delay}ms</span>
            </div>

            <Slider
              value={[delay]}
              onValueChange={([newDelay]) => setDelay(newDelay)}
              min={100}
              max={2000}
              step={100}
              className="py-4"
            />
          </div>

          <div className="text-sm text-muted-foreground bg-muted p-3 rounded-lg">
            Status: {isPlaying ? (
              <span className="text-green-500">Running</span>
            ) : (
              <span className="text-yellow-500">Paused</span>
            )}
          </div>
        </div>
      </Card>

      {/* Right Column - Documentation */}
      <Card className="p-6">
        <div className="space-y-6">
          <div>
            <h3 className="text-lg font-medium mb-2">About useInterval</h3>
            <p className="text-sm text-muted-foreground">
              A declarative interval hook that can be paused and resumed.
            </p>
          </div>

          <div className="space-y-4">
            <pre className="bg-muted p-3 rounded-md text-xs">
{`const [count, setCount] = useState(0)
const [delay, setDelay] = useState(1000)
const [isPlaying, setPlaying] = useState(false)

useInterval(
  () => {
    setCount(count + 1)
  },
  isPlaying ? delay : null
)`}
            </pre>

            <div className="space-y-4">
              <div>
                <h4 className="text-sm font-medium mb-2">Features</h4>
                <ul className="list-disc list-inside space-y-1 text-sm text-muted-foreground">
                  <li>Memory leak safe</li>
                  <li>Supports dynamic delays</li>
                  <li>Pause/resume functionality</li>
                  <li>TypeScript ready</li>
                </ul>
              </div>

              <div>
                <h4 className="text-sm font-medium mb-2">Common Use Cases</h4>
                <ul className="list-disc list-inside space-y-1 text-sm text-muted-foreground">
                  <li>Polling APIs</li>
                  <li>Countdown timers</li>
                  <li>Game loops</li>
                  <li>Animations</li>
                </ul>
              </div>

              <div className="text-sm text-muted-foreground p-3 bg-muted/50 rounded-lg">
                <p className="font-medium mb-1">Pro Tip:</p>
                Pass <code className="text-xs">null</code> as delay to pause the interval
              </div>
            </div>
          </div>
        </div>
      </Card>
    </div>
  )
}

Dependencies

More by Ghribi Ouassim

View all
  • useCopyToClipboard

    useCopyToClipboard

    70
  • useToggle

    useToggle

    35
  • useDebounceCallback

    useDebounceCallback

    23
  • useTimeout

    useTimeout

    13
  • useCounter

    useCounter

    10
  • useIsomorphicLayoutEffect

    useIsomorphicLayoutEffect

    10
  • useUnmount

    useUnmount

    10
  • useBoolean

    useBoolean

    8