1+ import { useEffect , useRef , useState } from 'react' ;
2+
13import { InfiniteData , useInfiniteQuery } from '@tanstack/react-query' ;
24
35import { getWines } from '@/lib/wineApi' ;
@@ -8,30 +10,60 @@ import { GetWinesResponse } from '@/types/wineListType';
810const PAGE_LIMIT = 8 ;
911const TEAM_ID = process . env . NEXT_PUBLIC_TEAM ;
1012
13+ function useDebounce < T > ( value : T ) {
14+ const debounceTimer = useRef < ReturnType < typeof setTimeout > | null > ( null ) ;
15+ const [ debouncedValue , setDebouncedValue ] = useState < T > ( ( ) => value ) ;
16+
17+ useEffect ( ( ) => {
18+ if ( debounceTimer . current ) clearTimeout ( debounceTimer . current ) ;
19+ debounceTimer . current = setTimeout ( ( ) => {
20+ setDebouncedValue ( value ) ;
21+ } , 1000 ) ;
22+
23+ return ( ) => {
24+ if ( debounceTimer . current ) clearTimeout ( debounceTimer . current ) ;
25+ } ;
26+ } , [ value ] ) ;
27+ return debouncedValue ;
28+ }
29+
1130export function useWineListQuery ( ) {
1231 const type = useFilterStore ( ( state ) => state . type ) ;
1332 const minPrice = useFilterStore ( ( state ) => state . minPrice ) ;
1433 const maxPrice = useFilterStore ( ( state ) => state . maxPrice ) ;
1534 const rating = useFilterStore ( ( state ) => state . rating ) ;
1635 const searchTerm = useWineSearchKeywordStore ( ( state ) => state . searchTerm ) ;
1736
37+ const debouncedType = useDebounce ( type ) ;
38+ const debouncedMinPrice = useDebounce ( minPrice ) ;
39+ const debouncedMaxPrice = useDebounce ( maxPrice ) ;
40+ const debouncedSearchTerm = useDebounce ( searchTerm ) ;
41+
1842 const apiRating = rating === 'all' ? undefined : Number ( rating ) ;
43+ const debouncedRating = useDebounce ( apiRating ) ;
1944
2045 return useInfiniteQuery < GetWinesResponse , unknown , InfiniteData < GetWinesResponse > > ( {
21- queryKey : [ 'wines' , { type, minPrice, maxPrice, rating : apiRating , name : searchTerm } ] ,
46+ queryKey : [
47+ 'wines' ,
48+ {
49+ type : debouncedType ,
50+ minPrice : debouncedMinPrice ,
51+ maxPrice : debouncedMaxPrice ,
52+ rating : debouncedRating ,
53+ name : debouncedSearchTerm ,
54+ } ,
55+ ] ,
2256 queryFn : ( { pageParam = 0 } ) => {
2357 const filters = {
24- type : type . toUpperCase ( ) ,
25- minPrice,
26- maxPrice,
27- rating : apiRating ,
28- name : searchTerm ,
58+ type : debouncedType . toUpperCase ( ) ,
59+ minPrice : debouncedMinPrice ,
60+ maxPrice : debouncedMaxPrice ,
61+ rating : debouncedRating ,
62+ name : debouncedSearchTerm ,
2963 } ;
3064
3165 const filteredParams = Object . fromEntries (
32- Object . entries ( filters ) . filter (
33- ( [ , value ] ) => value !== null && value !== undefined && value !== '' ,
34- ) ,
66+ Object . entries ( filters ) . filter ( ( [ , value ] ) => value !== null && value !== undefined ) ,
3567 ) ;
3668
3769 return getWines ( {
0 commit comments