Implement debounced search query

This commit is contained in:
2020-07-22 20:46:13 +02:00
parent af1594f375
commit 07f1a6c2ea
3 changed files with 54 additions and 13 deletions

View File

@@ -1,17 +1,54 @@
import React, { useState } from 'react';
import React, { useState, useCallback, useEffect } from 'react';
import { gql, useLazyQuery } from '@apollo/client';
import { Box, TextInput } from 'grommet';
import { FormSearch } from 'grommet-icons';
import { debounce } from 'lodash';
const SEARCH_ARTIST = gql`
query Artist($byName: String!) {
queryArtists(byName: $byName) {
name
}
}
`;
export const SearchBox = () => {
const [value, setValue] = useState('');
const [getArtist, { loading, data }] = useLazyQuery(SEARCH_ARTIST);
const [suggestions, setSuggestions] = useState(['']);
// TODO: Find a solution to have suggestions not showing when empty
let suggestions = [
'The Doors',
'The Doors With Eddie Vedder',
'The Doorstep Carolers',
'The Doors Experience',
'Darken the Doorstep',
];
// Debounce the database query, based on the following article:
// https://dev.to/reflexgravity/use-lodash-debouce-inside-a-functional-component-in-react-4g5j
const updateQuery = () => {
getArtist({ variables: { byName: value } });
};
const delayedQuery = useCallback(debounce(updateQuery, 500), [value]);
const handleChange = (e: any) => {
setValue(e.target.value);
};
useEffect(() => {
delayedQuery();
// Cancel previous debounce calls during useEffect cleanup.
return delayedQuery.cancel;
}, [value, delayedQuery]);
useEffect(() => {
// TODO: Maybe merge the two use effects?
if (data) {
const mapSuggestions: string[] = data.queryArtists.map(
(el: { name: string }) => {
return el.name;
},
);
const updatedSuggestions = mapSuggestions.slice(0, 5);
setSuggestions(updatedSuggestions);
}
}, [data]);
return (
<Box
@@ -22,14 +59,11 @@ export const SearchBox = () => {
>
<TextInput
value={value}
onChange={(event) => setValue(event.target.value)}
onChange={handleChange}
placeholder='Type an artist name'
icon={<FormSearch color='plain' />}
dropProps={{
overflow: 'visible',
}}
dropHeight='large'
suggestions={suggestions}
suggestions= {suggestions}
/>
</Box>
);