useDebounce
Delay execution until activity stops. Perfect for search inputs, form validation, and reducing API calls.
Live Demo
Try typing in the search box or clicking the button rapidly. Notice how the debounced value only updates after you stop.
🔍 Value Debouncing (Search)
Current Value: (empty)
Debounced Value: (empty)
💡 API call only fires after you stop typing for 500ms
🖱️ Function Debouncing (Button)
Execution Count
0
💡 Only executes after you stop clicking for 1 second
📝 Event Log
No events yet. Try typing or clicking!
💡 How It Works:
- Delays execution until activity stops
- Perfect for search inputs and form validation
- Reduces API calls and improves performance
- Only the last call executes after the delay
Code Examples
Search Input Debouncing
import { useDebounce } from "@uiblock/hooks";
import { useState, useEffect } from "react";
export default function SearchBox() {
const [searchTerm, setSearchTerm] = useState('');
const debouncedSearchTerm = useDebounce(searchTerm, 500);
useEffect(() => {
if (debouncedSearchTerm) {
// API call only fires after user stops typing
fetch(`/api/search?q=${debouncedSearchTerm}`)
.then(res => res.json())
.then(data => console.log(data));
}
}, [debouncedSearchTerm]);
return (
<input
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
placeholder="Search..."
/>
);
}Form Validation
import { useDebounce } from "@uiblock/hooks";
import { useState, useEffect } from "react";
export default function UsernameInput() {
const [username, setUsername] = useState('');
const [isAvailable, setIsAvailable] = useState<boolean | null>(null);
const debouncedUsername = useDebounce(username, 300);
useEffect(() => {
if (debouncedUsername) {
checkUsernameAvailability(debouncedUsername)
.then(setIsAvailable);
}
}, [debouncedUsername]);
return (
<div>
<input
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
{isAvailable !== null && (
<span>{isAvailable ? '✅ Available' : '❌ Taken'}</span>
)}
</div>
);
}Debounced Callback
import { useDebouncedCallback } from "@uiblock/hooks";
export default function AutoSave() {
const saveData = useDebouncedCallback(async (data) => {
await fetch('/api/save', {
method: 'POST',
body: JSON.stringify(data)
});
console.log('Saved!');
}, 1000);
return (
<textarea
onChange={(e) => saveData({ content: e.target.value })}
placeholder="Type to auto-save..."
/>
);
}How It Works
Here's the implementation:
import { useState, useEffect, useCallback, useRef } from 'react'
// Value debouncing
export function useDebounce<T>(value: T, delay: number): T {
const [debouncedValue, setDebouncedValue] = useState<T>(value)
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value)
}, delay)
return () => {
clearTimeout(handler)
}
}, [value, delay])
return debouncedValue
}
// Function debouncing
export function useDebouncedCallback<T extends (...args: any[]) => any>(
callback: T,
delay: number
): T {
const timeoutRef = useRef<NodeJS.Timeout | null>(null)
return useCallback(
((...args: Parameters<T>) => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current)
}
timeoutRef.current = setTimeout(() => {
callback(...args)
}, delay)
}) as T,
[callback, delay]
)
}API Reference
useDebounce
value: TThe value to debounce
delay: numberDelay in milliseconds
Returns: T - The debounced value
useDebouncedCallback
callback: TFunction to debounce
delay: numberDelay in milliseconds
Returns: T - Debounced version of the callback
💡 Use Cases
- Search autocomplete and suggestions
- Form validation (username, email availability)
- Auto-save functionality
- Reducing API calls
- Window resize handlers
- Text input processing