Lesson 9. Debouncing a user input 2. Debouncing the input with another state
The idea will be to have another state debouncedSearch, which will be updated
300 milliseconds after search. To do this, when search is updated, we will
call setTimeout to update debouncedSearch.
Note that there are a lot of ways to implement debouncing, each with its small differences. The one we’ll see here is the easiest one to understand and implement:
- If we set
searchto “A”, we start a timeout of 300 milliseconds, after which we updatedebouncedSearchto “A”. - If before the first timeout ends,
searchis updated to “AB”, we cancel the first timeout, then start a new one of 300 ms, at the end of which we updatedebouncedSearchto “AB”.
const [debouncedSearch, setDebouncedSearch] = useState(search)useEffect(() => {let timeout = setTimeout(() => {setDebouncedSearch(search)}, 300)return () => clearTimeout(timeout)}, [search])
With this variant, debouncedSearch will always be updated 300 milliseconds
after the last character is typed.
Another way to do would be, at the end of the timeout, to get the current
value of search (using a ref, see lesson 6). But let’s stay in the easy way
here and solve our problem with as few complexity as possible.
Here is the full code of our component using debouncing:
Result
Now the state search contains the value entered in the input, and
debouncedSearch the same value but updated 300 milliseconds later. This is
this last value that we want to use in the useEffect responsible for calling
the API and performing the search.
This debouncing behavior is very common, and you may need it in several places in your application(s), so maybe it is a good idea to extract it into a custom hook. What do you think?