I am trying to create a debounce search and initially when the field is empty the component renders after the provided setTimeout delay. But if I continue to search with the existing keyword it re-renders the List component on each key stroke. How to avoid that?
import { useEffect, useState } from 'react';
import useDebounce from './hooks/useDebounce';
import List from './components/List';
const App: React.FC = () => {
const [todo, setTodo] = useState<string>("");
const [query, setQuery] = useState<string | null>("");
let deBounceSearch = useDebounce(query, 2000);
useEffect(() => {
if (deBounceSearch) {
console.log('Searching...');
} else {
console.log('...');
}
}, [deBounceSearch]);
return (
<div className="App">
<input type="text" placeholder='Search anything' onChange={(e) => setQuery(e.target.value)} />
{deBounceSearch !== '' && (
<List />
)}
</div>
);
}
useDebounce.tsx
const useDebounce = (value: any, delay: number) => {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const handler = setTimeout(() => { setDebouncedValue(value) }, delay);
return () => {
clearTimeout(handler);
}
}, [value, delay]);
return debouncedValue;
}
export default useDebounce;
2
Answers
You can use useMemo to avoid re-render the
List
component every timequery
value changes:You also can take a look at
React.memo
hello man this is not the best to use debounce i suggest u try
lodash
debounce withuseMemo
.but for now the solution for your code is that you forgot to clear the timeout on every time the value change.
here the solution:
hope this help .