I need to implement tag search on user input, but input is fast and i don't want to fire DB call for every symbol user typed, so i was curios, is there a simple a good way to debounce api calls let's say - one time after 3 seconds delay?
For now i come up with this:
let searchDelay
async function handleTagSearch(e) {
clearTimeout(searchDelay)
tagSearchPhraseSet(e.target.value)
searchDelay = setTimeout(async () => {
if (e.target.value.length > 3) {
let res = await fetch('api/tag_seatch/' + e.target.value)
res = await res.json()
console.log(res)
}
}, 3000)
}
But is it a right approach?
Your solution looks promising, if you make sure that the searchDelay number is persisted between renders with e.g. a useRef hook.
Another way of going about it is to use a useEffect hook that is run every time the input value changes. From the function given to useEffect you can return a function that clears the timeout of the previous time it was run.
Example
const { useState, useEffect } = React;
function App() {
const [value, setValue] = useState("");
const [result, setResult] = useState(null);
useEffect(
() => {
if (value.length < 3) {
setResult(null);
return;
}
const timeout = setTimeout(() => {
setResult(Math.random());
}, 3000);
return () => clearTimeout(timeout);
},
[value]
);
return (
<div>
<input value={value} onChange={e => setValue(e.target.value)} />
<div>{result}</div>
</div>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With