Skip to content

Hook for handle functions with debounce #370

@GenLoya

Description

@GenLoya

Feature Request: useDebounceHandle

Summary

Propose adding a useDebounceHandle hook that debounces a handler function and exposes a pending state via React's useTransition.

Motivation

A common pattern in React apps is preventing a function (e.g. a search handler, form submission, or API call) from firing too frequently. While useDebounce covers debouncing values, there's no hook in the library for debouncing function calls directly — especially when you want to reflect the pending state in the UI.

Proposed API

const { schedule, isLoading } = useDebounceHandle(delay?: number, handle: (...args: any[]) => void)
  • schedule(...args) — call this instead of the original handler; it resets the debounce timer on each call.
  • isLoading — a boolean powered by useTransition, reflecting whether the handler is still pending/running.
  • delay — debounce delay in milliseconds (default: 1000).

Implementation

'use client'
import { useEffect, useRef, useTransition } from 'react'

export function useDebounceHandle(delay = 1000, handle) {
  const timeoutRef = useRef(null)
  const [isLoading, startTransition] = useTransition()

  const schedule = (...args) => {
    if (timeoutRef.current) clearTimeout(timeoutRef.current)
    timeoutRef.current = setTimeout(() => {
      startTransition(() => {
        handle(...args)
      })
    }, delay)
  }

  useEffect(() => {
    return () => {
      if (timeoutRef.current) clearTimeout(timeoutRef.current)
    }
  }, [])

  return { schedule, isLoading }
}

Example Usage

function SearchInput() {
  const { schedule, isLoading } = useDebounceHandle(500, (value) => {
    fetchResults(value)
  })

  return (
    <div>
      <input onChange={(e) => schedule(e.target.value)} />
      {isLoading && <span>Searching...</span>}
    </div>
  )
}

Question

Before considering this, I'd love to know — is there already a hook in this library that covers a similar use case? I looked through the docs but didn't find one that debounces a function call directly while also exposing a pending state. If there is, I'm happy to close this and use that instead!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions