-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuseListings.ts
More file actions
56 lines (48 loc) · 1.62 KB
/
useListings.ts
File metadata and controls
56 lines (48 loc) · 1.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import { useEffect } from "react";
import { useInView } from "react-intersection-observer";
import { useInfiniteQuery } from "@tanstack/react-query";
import { getItems, getSublets } from "@/lib/actions";
import { queryKeys } from "@/lib/queryKeys";
import { ListingTypes, PaginatedResponse, Listing } from "@/lib/types";
import { useFilters } from "@/providers/FiltersProvider";
const LISTING_FETCHERS = {
items: getItems,
sublets: getSublets,
} as const;
export type UseListingsParams<T extends ListingTypes> = {
type: T;
};
export function useListings<T extends ListingTypes>({ type }: UseListingsParams<T>) {
const { ref, inView } = useInView();
const { debouncedFilters } = useFilters();
const filters = debouncedFilters[type];
const queryFn = ({ pageParam = 1 }: { pageParam: unknown }) =>
LISTING_FETCHERS[type]({ pageParam, ...filters });
const { data, error, fetchNextPage, isFetchingNextPage, hasNextPage } = useInfiniteQuery<
PaginatedResponse<Listing>
>({
queryKey: queryKeys.listings(type, filters),
queryFn,
placeholderData: (previousData) => previousData,
initialPageParam: 1,
getNextPageParam(lastPage, allPages) {
return lastPage.results.length > 0 ? allPages.length + 1 : undefined;
},
staleTime: 1 * 60 * 1000, // 1 minute
gcTime: 5 * 60 * 1000, // 5 minutes
});
useEffect(() => {
if (inView) {
// this implements infinite scrolling (fetches next page when user scrolls to the bottom)
fetchNextPage();
}
}, [inView, fetchNextPage]);
return {
data,
error,
fetchNextPage,
isFetchingNextPage,
hasNextPage,
ref,
};
}