Debouncing delays execution until pause. Throttling limits execution frequency.
Debounce hook:
1import { useState, useEffect } from "react";23function useDebounce<T>(value: T, delay: number): T {4 const [debouncedValue, setDebouncedValue] = useState(value);56 useEffect(() => {7 const timer = setTimeout(() => setDebouncedValue(value), delay);8 return () => clearTimeout(timer);9 }, [value, delay]);1011 return debouncedValue;12}1314// Usage15function SearchInput() {16 const [query, setQuery] = useState("");17 const debouncedQuery = useDebounce(query, 500);1819 useEffect(() => {20 if (debouncedQuery) {21 search(debouncedQuery);22 }23 }, [debouncedQuery]);2425 return <input value={query} onChange={e => setQuery(e.target.value)} />;26}
Throttle hook:
1function useThrottle<T>(value: T, limit: number): T {2 const [throttledValue, setThrottledValue] = useState(value);3 const lastRun = useRef(Date.now());45 useEffect(() => {6 const handler = setTimeout(() => {7 if (Date.now() - lastRun.current >= limit) {8 setThrottledValue(value);9 lastRun.current = Date.now();10 }11 }, limit - (Date.now() - lastRun.current));1213 return () => clearTimeout(handler);14 }, [value, limit]);1516 return throttledValue;17}1819// Usage20function ScrollTracker() {21 const [scrollY, setScrollY] = useState(0);22 const throttledScrollY = useThrottle(scrollY, 100);2324 useEffect(() => {25 const handleScroll = () => setScrollY(window.scrollY);26 window.addEventListener("scroll", handleScroll);27 return () => window.removeEventListener("scroll", handleScroll);28 }, []);2930 return <div>Scroll: {throttledScrollY}px</div>;31}
When to use: