JAVASCRIPT
Create a Custom useDebounce Hook for Any Value
Implement a flexible custom useDebounce hook in React to delay updates of any state value, optimizing performance for actions like search filtering or window resizing.
import React, { useState, useEffect } from 'react';
// Custom hook for debouncing a value
function useDebounce(value, delay) {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
// Set a timeout to update debounced value after the specified delay
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);
// Cleanup function: Clear timeout if value changes or component unmounts
return () => {
clearTimeout(handler);
};
}, [value, delay]); // Only re-run if value or delay changes
return debouncedValue;
}
// Component using the custom hook
function SearchInput() {
const [searchTerm, setSearchTerm] = useState('');
const debouncedSearchTerm = useDebounce(searchTerm, 500); // Debounce by 500ms
// Simulate a search operation (e.g., filtering a list locally)
useEffect(() => {
if (debouncedSearchTerm) {
console.log('Performing search for:', debouncedSearchTerm);
// In a real app, you would filter a local list or make an API call here.
// For this example, we're just logging.
}
}, [debouncedSearchTerm]);
return (
<div style={{ padding: '20px', border: '1px solid #eee', borderRadius: '8px' }}>
<h3>Search Example (Debounced Input)</h3>
<input
type="text"
placeholder="Type to search..."
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
style={{ padding: '8px', border: '1px solid #ccc', borderRadius: '4px', width: '250px' }}
/>
<p style={{ marginTop: '10px', fontSize: '0.9em', color: '#666' }}>
Current Input: <strong>{searchTerm || '...'}</strong>
<br />
Debounced Value: <strong>{debouncedSearchTerm || '...'}</strong>
</p>
<p style={{ fontSize: '0.8em', color: '#999' }}>
(Search logic triggers only after 500ms of no new input)
</p>
</div>
);
}
// Usage example:
// function App() {
// return <SearchInput />;
// }
How it works: This custom `useDebounce` hook takes any value and a delay, returning a new "debounced" value that only updates after the specified delay has passed without the original value changing. This is achieved using `useEffect` with a `setTimeout` and its cleanup function. It's incredibly useful for optimizing performance by delaying costly operations (like filtering a large list or validating input) until the user has paused their input, preventing excessive computations or re-renders.