I'm trying to implement autocomplete search with debounce,
Below is my attempt using lodash's debounce, it seems debouncing is not working.
I'm seeing every character being searched as I type
const [query, setQuery] = useState('')
const _search = () => {
console.log('query: ', query)
// network search request
}
const search = _.debounce(_search, 300)
useEffect(() => {
search()
}, [query])
const handleChangeQuery = useCallback((query) => {
setQuery(query)
})
** edit **
Following works, yes I mostly got hint from https://stackoverflow.com/a/54666498/433570 although I think it is very slightly different
Where the linked post chains event setQuery => useEffect => useRef => debounce Here I'm chaining useCallback => useRef => debounce
Although the core problem (according to the linked post) is you recreate variables inside your component everytime your functional component is called.
useRef saves it.
I understood useCallback remembers the function but it also loses when the dependant variable changes
It's kinda vague what it means, I thought useCallback gives you memoized function, but if you change the following code from useRef to useCallback it stops working.. (event though we don't use dependant variable such as useCallback(() => {}, [var])
const ReviewMetaSelect = (props) => {
const [query, setQuery] = useState('')
const search = useRef(_.debounce(query => {
console.log('query: ', query)
}, 300))
// or u can use this
//const search = useCallback(_.debounce(query => {
//console.log('query: ', query)
//}, 300), [])
const handleChangeQuery = useCallback((query) => {
setQuery(query)
search.current(query) // or search(query) with useCallback
})
return (
<View>
<TextInput
value={query}
onChangeText={handleChangeQuery}
/>
</View>
)
}
You can create your custom component Input with a debounce (or use inside another component), with out necesity of a library
For example like some this:
import React, { useEffect, useState } from 'react';
const InputDebounce = () => {
const [text, setText] = useState('');
useEffect(() => {
const timeoutId = setTimeout(() => {
console.log(text)
//some function here
}, 500);
return () => clearTimeout(timeoutId)
}, [text])
return <input type="text" onChange={(e) => setText(e.target.value)} />
};
export default InputDebounce;
Is very important define the clearTimeOut a return insde of the useEffect,to this working ok.
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