Implement debounced search query
This commit is contained in:
parent
af1594f375
commit
07f1a6c2ea
@ -8,12 +8,14 @@
|
|||||||
"@testing-library/react": "^9.3.2",
|
"@testing-library/react": "^9.3.2",
|
||||||
"@testing-library/user-event": "^7.1.2",
|
"@testing-library/user-event": "^7.1.2",
|
||||||
"@types/jest": "^24.0.0",
|
"@types/jest": "^24.0.0",
|
||||||
|
"@types/lodash": "^4.14.158",
|
||||||
"@types/node": "^12.0.0",
|
"@types/node": "^12.0.0",
|
||||||
"@types/react": "^16.9.0",
|
"@types/react": "^16.9.0",
|
||||||
"@types/react-dom": "^16.9.0",
|
"@types/react-dom": "^16.9.0",
|
||||||
"graphql": "^15.3.0",
|
"graphql": "^15.3.0",
|
||||||
"grommet": "^2.14.0",
|
"grommet": "^2.14.0",
|
||||||
"grommet-icons": "^4.4.0",
|
"grommet-icons": "^4.4.0",
|
||||||
|
"lodash": "^4.17.19",
|
||||||
"react": "^16.13.1",
|
"react": "^16.13.1",
|
||||||
"react-dom": "^16.13.1",
|
"react-dom": "^16.13.1",
|
||||||
"react-scripts": "3.4.1",
|
"react-scripts": "3.4.1",
|
||||||
|
@ -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 { Box, TextInput } from 'grommet';
|
||||||
import { FormSearch } from 'grommet-icons';
|
import { FormSearch } from 'grommet-icons';
|
||||||
|
import { debounce } from 'lodash';
|
||||||
|
|
||||||
|
const SEARCH_ARTIST = gql`
|
||||||
|
query Artist($byName: String!) {
|
||||||
|
queryArtists(byName: $byName) {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
export const SearchBox = () => {
|
export const SearchBox = () => {
|
||||||
const [value, setValue] = useState('');
|
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 = [
|
// Debounce the database query, based on the following article:
|
||||||
'The Doors',
|
// https://dev.to/reflexgravity/use-lodash-debouce-inside-a-functional-component-in-react-4g5j
|
||||||
'The Doors With Eddie Vedder',
|
const updateQuery = () => {
|
||||||
'The Doorstep Carolers',
|
getArtist({ variables: { byName: value } });
|
||||||
'The Doors Experience',
|
};
|
||||||
'Darken the Doorstep',
|
|
||||||
];
|
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 (
|
return (
|
||||||
<Box
|
<Box
|
||||||
@ -22,14 +59,11 @@ export const SearchBox = () => {
|
|||||||
>
|
>
|
||||||
<TextInput
|
<TextInput
|
||||||
value={value}
|
value={value}
|
||||||
onChange={(event) => setValue(event.target.value)}
|
onChange={handleChange}
|
||||||
placeholder='Type an artist name'
|
placeholder='Type an artist name'
|
||||||
icon={<FormSearch color='plain' />}
|
icon={<FormSearch color='plain' />}
|
||||||
dropProps={{
|
|
||||||
overflow: 'visible',
|
|
||||||
}}
|
|
||||||
dropHeight='large'
|
dropHeight='large'
|
||||||
suggestions={suggestions}
|
suggestions= {suggestions}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
@ -1607,6 +1607,11 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339"
|
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339"
|
||||||
integrity sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==
|
integrity sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==
|
||||||
|
|
||||||
|
"@types/lodash@^4.14.158":
|
||||||
|
version "4.14.158"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.158.tgz#b38ea8b6fe799acd076d7a8d7ab71c26ef77f785"
|
||||||
|
integrity sha512-InCEXJNTv/59yO4VSfuvNrZHt7eeNtWQEgnieIA+mIC+MOWM9arOWG2eQ8Vhk6NbOre6/BidiXhkZYeDY9U35w==
|
||||||
|
|
||||||
"@types/minimatch@*":
|
"@types/minimatch@*":
|
||||||
version "3.0.3"
|
version "3.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
|
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
|
||||||
|
Loading…
Reference in New Issue
Block a user