When working with events like search inputs, scrolling, or resizing, it's important to optimize performance by reducing unnecessary function calls. Two common techniques for this are:
useEffect
and setTimeout
Debouncing is useful when handling search inputs or resizing where you want to execute a function only after the user stops typing/moving.
useDebounce
Hookimport { useState, useEffect } from "react";
function useDebounce(value, delay) {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => clearTimeout(handler); // Cleanup previous timer
}, [value, delay]);
return debouncedValue;
}
function SearchBar() {
const [query, setQuery] = useState("");
const debouncedQuery = useDebounce(query, 500); // Waits 500ms after last input
useEffect(() => {
if (debouncedQuery) {
console.log("Fetching results for:", debouncedQuery);
}
}, [debouncedQuery]);
return (
<input
type="text"
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Search..."
/>
);
}
useRef
and setTimeout
:Throttling ensures a function executes at most once per interval. It's useful for scrolling, resizing, or button spamming.
useThrottle
Hookimport { useState, useEffect, useRef } from "react";
function useThrottle(value, delay) {
const [throttledValue, setThrottledValue] = useState(value);
const lastExecuted = useRef(Date.now());
useEffect(() => {
const handler = setTimeout(() => {
if (Date.now() - lastExecuted.current >= delay) {
setThrottledValue(value);
lastExecuted.current = Date.now();
}
}, delay - (Date.now() - lastExecuted.current));
return () => clearTimeout(handler);
}, [value, delay]);
return throttledValue;
}
function ScrollLogger() {
const [scrollPos, setScrollPos] = useState(0);
const throttledScrollPos = useThrottle(scrollPos, 1000); // Throttles updates every 1s
useEffect(() => {
const handleScroll = () => {
setScrollPos(window.scrollY);
};
window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
}, []);
return <p>Scroll Position: {throttledScrollPos}</p>;
}
Feature | Debounce | Throttle |
---|---|---|
Use Case | Search input, API calls | Scroll, resize, click events |
Execution | Fires after user stops | Fires at fixed intervals |
Example | Auto-suggest search bar | Tracking scroll position |