-
Notifications
You must be signed in to change notification settings - Fork 67
/
usePagination.ts
86 lines (73 loc) 路 2.21 KB
/
usePagination.ts
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import {UseQuery} from '@reduxjs/toolkit/dist/query/react/buildHooks';
import {useCallback, useState} from 'react';
import {useSearchParams} from 'react-router-dom';
type TParams<P> = P & {
take?: number;
};
export interface PaginationResponse<T> {
total: number;
items: T[];
}
export interface IPagination<T> {
hasNext: boolean;
hasPrev: boolean;
isEmpty: boolean;
isFetching: boolean;
isLoading: boolean;
list: T[];
loadNext: () => void;
loadPrev: () => void;
loadPage: (pg: number) => void;
search: (query: string) => void;
page: number;
total: number;
take: number;
}
function totalLoaded(list: Array<any>, params: {page: number; query: string}, take: number) {
const length = list?.length || 0;
return params.page === 0 ? length : params.page * take + length;
}
const usePagination = <T, P>(
useGetDataListQuery: UseQuery<any>,
{take = 20, ...queryParams}: TParams<P>
): IPagination<T> => {
const [searchParams] = useSearchParams();
const defaultPage = searchParams.get('page') ? Number(searchParams.get('page')) - 1 : 0;
const [params, setParams] = useState<{page: number; query: string}>({page: defaultPage, query: ''});
const {data, isFetching, isLoading} = useGetDataListQuery({
skip: params.page * take,
take,
...queryParams,
...(params.query ? {query: params.query} : {}),
});
const list = (data as any)?.items as T[];
const total = (data as any)?.total as number;
const loadNext = useCallback(() => {
setParams(prevParams => ({...prevParams, page: prevParams.page + 1}));
}, []);
const loadPrev = useCallback(() => {
setParams(prevParams => ({...prevParams, page: prevParams.page - 1}));
}, []);
const loadPage = useCallback((pg: number) => {
setParams(prevParams => ({...prevParams, page: pg}));
}, []);
const search = (query: string) => {
setParams({page: 0, query});
};
return {
loadPage,
hasNext: totalLoaded(list, params, take) < total,
hasPrev: params.page > 0,
isEmpty: params.page === 0 && !list?.length && !isLoading && !isFetching,
isFetching,
isLoading,
list: list ?? [],
loadNext,
loadPrev,
search,
page: params.page + 1,
total,
take,
};
};
export default usePagination;