-
Notifications
You must be signed in to change notification settings - Fork 0
useAsyncDebounce
Saurav-TB-Pandey edited this page Aug 8, 2026
·
2 revisions
Debounces an asynchronous callback, useful for preventing spam API calls when a user types in a search box. It manages loading state and only resolves the final promise after the debounce delay.
The simplest possible implementation.
import { useState } from 'react';
import { useAsyncDebounce } from 'react-hook-lab';
function BasicSearch() {
const [query, setQuery] = useState('');
const { result, loading } = useAsyncDebounce(async () => {
return await fetch(`/api/search?q=${query}`).then(res => res.json());
});
return (
<div>
<input value={query} onChange={e => setQuery(e.target.value)} />
{loading ? <p>Loading...</p> : <p>Results: {result?.length}</p>}
</div>
);
}Providing a custom delay to wait for the user to stop typing.
import { useState } from 'react';
import { useAsyncDebounce } from 'react-hook-lab';
function AutoComplete() {
const [query, setQuery] = useState('');
const { result, loading, error } = useAsyncDebounce(async () => {
if (!query) return [];
const response = await fetch(`/api/search?q=${query}`);
return await response.json();
}, 500); // Wait 500ms after last change
return (
<div>
<input placeholder="Search..." value={query} onChange={e => setQuery(e.target.value)} />
{loading && <span>Searching...</span>}
{error && <span>Error!</span>}
<ul>
{result?.map(item => <li key={item.id}>{item.name}</li>)}
</ul>
</div>
);
}An exhaustive example handling both synchronous and asynchronous debounced returns, and catching errors.
import { useState } from 'react';
import { useAsyncDebounce } from 'react-hook-lab';
function AdvancedValidation() {
const [username, setUsername] = useState('');
const { result: isValid, loading, error } = useAsyncDebounce(async () => {
if (username.length < 3) return false;
// Asynchronous validation API call
const res = await fetch(`/api/validate-username`, {
method: 'POST',
body: JSON.stringify({ username })
});
if (!res.ok) throw new Error("Validation server down");
const data = await res.json();
return data.available;
}, 750);
return (
<div>
<label>Choose Username:</label>
<input value={username} onChange={e => setUsername(e.target.value)} />
{loading && <div>Checking availability...</div>}
{error && <div style={{color:'red'}}>{error.message}</div>}
{!loading && !error && username.length >= 3 && (
<div style={{color: isValid ? 'green' : 'red'}}>
{isValid ? 'Available!' : 'Taken'}
</div>
)}
</div>
);
}-
callback(Required)- Type:
() => T | Promise<T> - Description: The function (synchronous or asynchronous) to debounce. It is re-evaluated every time it changes, so ensure dependencies used inside are captured (e.g. by wrapping it in
useCallbackor relying on state variables).
- Type:
-
delay- Type:
number - Default:
300 - Description: The debounce delay in milliseconds. The callback will only execute after this amount of time has passed since the last render or update.
- Type:
Returns UseAsyncDebounceReturn<T>:
-
result(T | undefined): The resolved value returned by thecallback. -
loading(boolean): True during the debounce waiting period AND while the promise is resolving. -
error(unknown): Any error caught during the asynchronous execution.
Built with ❤️ by Saurav-TB-Pandey. | Report an Issue | NPM