useDebounce
Delay value updates until after a pause in changes
A React hook that debounces a value, useful for search inputs and expensive operations.
Usage
import { useDebounce } from "@your-org/react-utils";function SearchComponent() {const [searchTerm, setSearchTerm] = useState("");const debouncedSearch = useDebounce(searchTerm, 500);useEffect(() => {if (debouncedSearch) {// API call with debounced valuefetchResults(debouncedSearch);}}, [debouncedSearch]);return (<inputvalue={searchTerm}onChange={(e) => setSearchTerm(e.target.value)}placeholder="Search..."/>);}
Features
- Reduces API calls and expensive computations
- Configurable delay
- Automatic cleanup on unmount
- Type-safe with TypeScript generics
API Reference
Parameters
value(T) - The value to debouncedelay(number) - Delay in milliseconds (default: 500)
Returns
Returns the debounced value of type T.
Implementation
import { useEffect, useState } from "react";export function useDebounce<T>(value: T, delay: number = 500): T {const [debouncedValue, setDebouncedValue] = useState<T>(value);useEffect(() => {const handler = setTimeout(() => {setDebouncedValue(value);}, delay);return () => {clearTimeout(handler);};}, [value, delay]);return debouncedValue;}
Examples
Search with API Calls
function UserSearch() {const [query, setQuery] = useState("");const debouncedQuery = useDebounce(query, 300);const [results, setResults] = useState([]);const [loading, setLoading] = useState(false);useEffect(() => {if (!debouncedQuery) {setResults([]);return;}setLoading(true);searchUsers(debouncedQuery).then(setResults).finally(() => setLoading(false));}, [debouncedQuery]);return (<div><inputvalue={query}onChange={(e) => setQuery(e.target.value)}placeholder="Search users..."/>{loading && <Spinner />}<UserList users={results} /></div>);}
Auto-save Form
function AutoSaveForm() {const [formData, setFormData] = useState({ title: "", content: "" });const debouncedFormData = useDebounce(formData, 1000);useEffect(() => {// Auto-save after user stops typing for 1 secondif (debouncedFormData.title || debouncedFormData.content) {saveDraft(debouncedFormData);}}, [debouncedFormData]);return (<form><inputvalue={formData.title}onChange={(e) =>setFormData((prev) => ({ ...prev, title: e.target.value }))}/><textareavalue={formData.content}onChange={(e) =>setFormData((prev) => ({ ...prev, content: e.target.value }))}/><p className="text-sm text-gray-500">Draft saved automatically</p></form>);}
Window Resize Handler
function ResponsiveChart() {const [dimensions, setDimensions] = useState({ width: 0, height: 0 });const debouncedDimensions = useDebounce(dimensions, 200);useEffect(() => {const handleResize = () => {setDimensions({width: window.innerWidth,height: window.innerHeight,});};window.addEventListener("resize", handleResize);handleResize();return () => window.removeEventListener("resize", handleResize);}, []);return (<Chartwidth={debouncedDimensions.width}height={debouncedDimensions.height}/>);}