Reputation: 2432
I want to execute a function (query a search service) when use stops typing (or hits enter) I saw some examples using lodash Debounce
I´m playing with react hooks and wanted to see if is possible to achieve this without any external libraries.
import React, { useState } from 'react';
import Api from './Api'
const Search = (props) => {
const [keyword, setKeyword] = useState();
const [results, setResults] = useState([]);
let timeout;
const handleSearch = (event) => {
setKeyword(event.target.value);
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(() => {
timeout = null;
if (keyword) {
callSearchService()
}
}, 1000);
}
const callSearchService = () => {
Api.search(keyword)
.then(
results => setResults(results),
error => console.log(error)
)
}
return (
<input type="search" onKeyUp={(e) => handleSearch(e)} />
)
}
the execution is being delayed by 1000ms but then the function is called one time per character (except for the last character. that´s not being executed, I tried using onChange instead of onKeyUp, but same issue). i probably put the timeout in the wrong place. thanks for your infinite wisdom
Upvotes: 2
Views: 2595
Reputation: 16606
Definitely! You can implement your own debounce functionality using useEffect
and useState
. In this example, the value
is your user input and the code inside the setTimeout
callback will only execute when value
hasn't changed after 1 second.
const [value, setValue] = useState("");
useEffect(() => {
const callSearchService = () => {
Api.search(value)
.then(
results => setResults(results),
error => console.log(error)
)
}
let debouncer = setTimeout(() => {
callSearchService();
}, 1000);
return () => {
clearTimeout(debouncer);
}
}, [value]);
What's really important here is the "cleanup" function that clears the timeout if value
changes. If 1 second actually passes without any value
changes, the code inside your setTimeout
callback function will actually execute.
Upvotes: 6