Ghribi Ouassim

useDebounceCallback

Component 23

About

Delay function execution with useDebounceCallback, providing options for canceling, flushing, and checking if a call is pending.

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

Code

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

Usage.tsx

'use client'

import { useDebounceCallback } from "@/components/hooks/use-debounce-callback"
import { Button } from "@/components/ui/button"
import { Card } from "@/components/ui/card"
import { Input } from "@/components/ui/input"
import { Slider } from "@/components/ui/slider"
import { useState, useCallback } from "react"
import { toast } from "sonner"
import { Clock, Loader2 } from "lucide-react"

export function UseDebounceCallbackDemo() {
  const [value, setValue] = useState("")
  const [delay, setDelay] = useState(500)
  const [isPending, setIsPending] = useState(false)

  const mockApiCall = async (searchTerm: string) => {
    setIsPending(true)
    try {
      await new Promise(resolve => setTimeout(resolve, 500))
      toast.success(`API called with: "${searchTerm}"`)
    } finally {
      setIsPending(false)
    }
  }

  const debouncedSearch = useDebounceCallback(
    useCallback(async (searchTerm: string) => {
      setValue(searchTerm)
      await mockApiCall(searchTerm)
    }, []),
    delay
  )

  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">Live Demo</h3>
            <p className="text-sm text-muted-foreground">
              Type to see debounced API calls in action
            </p>
          </div>

          <div className="space-y-4">
            <div className="relative">
              <Input
                type="text"
                placeholder="Start typing..."
                onChange={(e) => debouncedSearch(e.target.value)}
                className="pr-8"
              />
              {isPending && (
                <Loader2 className="w-4 h-4 absolute right-3 top-3 animate-spin text-muted-foreground" />
              )}
            </div>

            <div className="space-y-2">
              <div className="flex items-center gap-2 text-sm">
                <Clock className="w-4 h-4" />
                <span>Debounce delay:</span>
                <span className="font-mono">{delay}ms</span>
              </div>

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

          <div className="p-3 rounded-lg bg-muted">
            <div className="text-sm font-medium mb-1">Current Value:</div>
            <code className="text-xs">
              {value || 'Empty'}
            </code>
          </div>

          <div className="flex gap-2">
            <Button
              variant="outline"
              size="sm"
              onClick={() => debouncedSearch.cancel()}
            >
              Cancel Pending
            </Button>
            <Button
              variant="outline"
              size="sm"
              onClick={() => debouncedSearch.flush()}
            >
              Flush Pending
            </Button>
          </div>
        </div>
      </Card>

      {/* Right Column - Documentation */}
      <Card className="p-6">
        <div className="space-y-6">
          <div>
            <h3 className="text-lg font-medium mb-2">Hook Usage</h3>
            <pre className="bg-muted p-3 rounded-md text-xs">
{`const debouncedFn = useDebounceCallback(
  (value) => {
    // Your callback logic
  },
  500, // delay in ms
  {
    leading: false,
    trailing: true,
  }
)

// Control methods
debouncedFn.cancel() // Cancel pending
debouncedFn.flush()  // Execute immediately
debouncedFn.isPending() // Check status`}
            </pre>
          </div>

          <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>Debounces function calls</li>
                <li>Configurable delay</li>
                <li>Cancel pending executions</li>
                <li>Force immediate execution</li>
                <li>Check pending status</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>Search input handling</li>
                <li>Form validation</li>
                <li>API request throttling</li>
                <li>Window resize handlers</li>
              </ul>
            </div>
          </div>
        </div>
      </Card>
    </div>
  )
}

Dependencies

More by Ghribi Ouassim

View all
  • useCopyToClipboard

    useCopyToClipboard

    70
  • useToggle

    useToggle

    35
  • useTimeout

    useTimeout

    13
  • useInterval

    useInterval

    12
  • useCounter

    useCounter

    10
  • useIsomorphicLayoutEffect

    useIsomorphicLayoutEffect

    10
  • useUnmount

    useUnmount

    10
  • useBoolean

    useBoolean

    8