Last active
March 20, 2022 14:41
-
-
Save guimochila/4fb10a0c1a858ddc6cd0596040394c94 to your computer and use it in GitHub Desktop.
Downshift and react-query
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { resetIdCounter, useCombobox } from 'downshift' | |
import Image from 'next/image' | |
import { useEffect, useRef, useState } from 'react' | |
import debounce from 'lodash/debounce' | |
import { DropDown, DropDownItem, SearchStyles } from './styled/DropDown' | |
import useSearch from '../hooks/useSearch' | |
function Search() { | |
resetIdCounter() | |
const [searchTerm, setSearchTerm] = useState<string | undefined>('') | |
const { data, isLoading, refetch } = useSearch(searchTerm) | |
const debouncedFindItem = useRef(debounce(refetch, 350)) | |
const items = data?.searchTerms || [] | |
const { | |
getMenuProps, | |
getInputProps, | |
getComboboxProps, | |
getItemProps, | |
highlightedIndex, | |
isOpen, | |
inputValue, | |
} = useCombobox({ | |
items, | |
onSelectedItemChange() { | |
console.log('Selected Item change') | |
}, | |
}) | |
useEffect(() => { | |
const currentDebounceRef = debouncedFindItem.current | |
return () => currentDebounceRef.cancel() | |
}, []) | |
useEffect(() => { | |
async function updateSearch() { | |
setSearchTerm(inputValue) | |
await debouncedFindItem.current() | |
} | |
updateSearch() | |
}, [inputValue]) | |
console.log(searchTerm) | |
return ( | |
<SearchStyles> | |
<div {...getComboboxProps()}> | |
<input | |
{...getInputProps({ | |
type: 'search', | |
placeholder: 'Search for an Item', | |
id: 'search', | |
className: isLoading ? 'loading' : '', | |
})} | |
/> | |
</div> | |
<DropDown {...getMenuProps()}> | |
{isOpen && | |
items.map((item, index) => ( | |
<DropDownItem | |
key={item.id} | |
{...getItemProps({ item })} | |
highlighted={index === highlightedIndex} | |
> | |
<Image | |
src={item.photo.image.publicUrlTransformed} | |
alt={item.name} | |
width={40} | |
height={40} | |
/> | |
{item.name} | |
</DropDownItem> | |
))} | |
{isOpen && !items.length ? ( | |
<DropDownItem highlighted={false}> | |
Sorry, no items for {searchTerm} | |
</DropDownItem> | |
) : null} | |
</DropDown> | |
</SearchStyles> | |
) | |
} | |
export default Search |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { gql } from 'graphql-request' | |
import { useQuery } from 'react-query' | |
import { Product } from '../@types/graphql-generated' | |
import gqlClient from '../utils/requestClient' | |
const SEARCH_PRODUCTS_QUERY = gql` | |
query SEARCH_PRODUCTS_QUERY($searchTerm: String!) { | |
searchTerms: products( | |
where: { | |
OR: [ | |
{ name: { contains: $searchTerm } } | |
{ description: { contains: $searchTerm } } | |
] | |
} | |
) { | |
id | |
name | |
photo { | |
image { | |
publicUrlTransformed | |
} | |
} | |
} | |
} | |
` | |
function useSearch(searchTerm: string | undefined) { | |
return useQuery<{ searchTerms: Product[] }>( | |
['search'], | |
async () => { | |
const items = await gqlClient.request(SEARCH_PRODUCTS_QUERY, { | |
searchTerm, | |
}) | |
return items | |
}, | |
{ | |
enabled: false, | |
cacheTime: 0, | |
retry: false, | |
}, | |
) | |
} | |
export default useSearch |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment