I've been trying to make a component in NextJS that uses searches youtube based on input given. To reduce the number of API calls made, I'm using lodash debounce with the useCallback hook but I keep getting this error: TypeError: search(...) is undefined
Here's the code that I wrote:
export default function Player() {
const [modalVisibility, setModalVisibility] = useState(true);
const [searchQuery, setSearchQuery] = useState('');
const [searchResults, setSearchResults] = useState([]);
const search = useCallback(
debounce(async (keyword) => {
const response = await fetch("http://localhost:3000/api/search/" + keyword);
const data = await response.json();
return data;
}, 500),
[]
);
useEffect(() => {
if (searchQuery) {
search(searchQuery).then((results) => setSearchResults(results));
console.log(searchQuery)
console.log(searchResults)
} else {
setSearchResults([])
}
}, [searchQuery])
return (
<Modal label={'Search for videos'} show={modalVisibility} handleClose={() => setModalVisibility(false)}>
<div>
<IoSearch size='1.25em' color={searchQuery ? '#000' : '#9ca3af'}/>
<input type="text" value={searchQuery} onChange={(e) => setSearchQuery(e.target.value)} placeholder="eg: 'Standup Comedy'"/>
</div>
<SearchResults results={searchResults}/>
</Modal>
)
}
Can anyone help me figure out why my search function is undefined?
debounce
does not return a value from inner function unless you specify leading: true
option for it.
So it is not your search
is undefined, but there is no promised and no then(...)
returned from search(...)
invocation.
Anyway I would suggest you to move your setSearchResults
inside search
function. You would still have race condition in case user types something and then quickly deletes query.