A common requirement in search inputs is debouncing.
Debouncing delays execution until the user stops typing for a defined
interval. This prevents unnecessary calls such as repeated API requests.
This example demonstrates how to implement debounced search in a React
functional component using:
useStateuseRefuseEffectlodash/debounce
Key Idea
Create a debounced version of the search function once, then trigger it
whenever the input state changes.
useRef stores the debounced function so it persists across renders.
Implementation
import React, { useRef, useEffect, useState } from "react";
import debounce from "lodash/debounce";
const MyComponent = () => {
const [searchTerm, setSearchTerm] = useState("");
const debouncedSearch = useRef(
debounce((term) => {
performSearch(term);
}, 500)
).current;
useEffect(() => {
debouncedSearch(searchTerm);
}, [searchTerm]);
function onSearchChange(event) {
setSearchTerm(event.target.value);
}
function performSearch(term) {
// Execute search logic here
}
return (
<input
type="text"
value={searchTerm}
onChange={onSearchChange}
/>
);
};
export default MyComponent;
How It Works
1. Store Input State
useState stores the current search input.
const [searchTerm, setSearchTerm] = useState("");
2. Create a Debounced Function
useRef ensures the debounced function is created once and reused
across renders.
const debouncedSearch = useRef(
debounce((term) => performSearch(term), 500)
).current;
Delay: 500 ms
3. Trigger Search on Input Change
useEffect calls the debounced function whenever searchTerm changes.
useEffect(() => {
debouncedSearch(searchTerm);
}, [searchTerm]);
4. Update Input Value
The input handler updates the state.
function onSearchChange(event) {
setSearchTerm(event.target.value);
}
Result
Behavior:
- User types into the input
searchTermupdates immediately- The search function runs only after the user stops typing for 500
ms
Benefits:
- Fewer API calls
- Reduced UI jitter
- Improved performance
Member discussion: