@@ -9,10 +9,14 @@ const SCROLL_POSITION_GAP = 400;
99type InfinityListArgs = Partial < Record < string , unknown > > ;
1010
1111type ListResponse < DataItem > = DataItem [ ] ;
12+ type ResponseWithDataProp < DataItem > = { data : ListResponse < DataItem > ; total_count : number } ;
13+
14+ type LazyQueryResponse < DataItem > = ResponseWithDataProp < DataItem > | ListResponse < DataItem > ;
1215
1316type UseInfinityParams < DataItem , Args extends InfinityListArgs > = {
14- useLazyQuery : UseLazyQuery < QueryDefinition < Args , any , any , ListResponse < DataItem > , any > > ;
17+ useLazyQuery : UseLazyQuery < QueryDefinition < Args , any , any , LazyQueryResponse < DataItem > , any > > ;
1518 args : { limit ?: number } & Args ;
19+ getResponseItems ?: ( listItem : DataItem ) => Partial < Args > ;
1620 getPaginationParams : ( listItem : DataItem ) => Partial < Args > ;
1721 skip ?: boolean ;
1822 // options?: UseQueryStateOptions<QueryDefinition<Args, any, any, Data[], any>, Record<string, any>>;
@@ -26,32 +30,50 @@ export const useInfiniteScroll = <DataItem, Args extends InfinityListArgs>({
2630 skip,
2731} : UseInfinityParams < DataItem , Args > ) => {
2832 const [ data , setData ] = useState < ListResponse < DataItem > > ( [ ] ) ;
33+ const [ totalCount , setTotalCount ] = useState < number | void > ( ) ;
2934 const scrollElement = useRef < HTMLElement > ( document . documentElement ) ;
3035 const isLoadingRef = useRef < boolean > ( false ) ;
36+ const isDisabledMoreRef = useRef < boolean > ( false ) ;
3137 const lastRequestParams = useRef < Args | undefined > ( undefined ) ;
32- const [ disabledMore , setDisabledMore ] = useState ( false ) ;
3338 const { limit, ...argsProp } = args ;
3439 const lastArgsProps = useRef < Partial < Args > > ( null ) ;
3540
3641 const [ getItems , { isLoading, isFetching } ] = useLazyQuery ( { ...args } as Args ) ;
3742
3843 const getDataRequest = ( params : Args ) => {
39- lastRequestParams . current = params ;
44+ if ( isEqual ( params , lastRequestParams . current ) ) {
45+ return Promise . reject ( ) ;
46+ }
4047
41- return getItems ( {
48+ const request = getItems ( {
4249 limit,
4350 ...params ,
4451 } as Args ) . unwrap ( ) ;
52+
53+ request . then ( ( ) => {
54+ lastRequestParams . current = { ...params } ;
55+ } ) ;
56+
57+ return request ;
4558 } ;
4659
4760 const getEmptyList = ( ) => {
4861 isLoadingRef . current = true ;
4962
5063 setData ( [ ] ) ;
5164
52- getDataRequest ( argsProp as Args ) . then ( ( result ) => {
53- setDisabledMore ( false ) ;
54- setData ( result as ListResponse < DataItem > ) ;
65+ getDataRequest ( argsProp as Args ) . then ( ( result : LazyQueryResponse < DataItem > ) => {
66+ // setDisabledMore(false);
67+ isDisabledMoreRef . current = false ;
68+
69+ if ( 'data' in result ) {
70+ setData ( result . data as ListResponse < DataItem > ) ;
71+ setTotalCount ( result . total_count ) ;
72+ } else {
73+ setData ( result as ListResponse < DataItem > ) ;
74+ setTotalCount ( ) ;
75+ }
76+
5577 isLoadingRef . current = false ;
5678 } ) ;
5779 } ;
@@ -64,7 +86,7 @@ export const useInfiniteScroll = <DataItem, Args extends InfinityListArgs>({
6486 } , [ argsProp , lastArgsProps , skip ] ) ;
6587
6688 const getMore = async ( ) => {
67- if ( isLoadingRef . current || disabledMore || skip ) {
89+ if ( isLoadingRef . current || isDisabledMoreRef . current || skip ) {
6890 return ;
6991 }
7092
@@ -76,18 +98,28 @@ export const useInfiniteScroll = <DataItem, Args extends InfinityListArgs>({
7698 ...getPaginationParams ( data [ data . length - 1 ] ) ,
7799 } as Args ) ;
78100
79- if ( result . length > 0 ) {
80- setData ( ( prev ) => [ ...prev , ...result ] ) ;
101+ let listResponse : ListResponse < DataItem > ;
102+
103+ if ( 'data' in result ) {
104+ listResponse = result . data ;
105+ setTotalCount ( result . total_count ) ;
106+ } else {
107+ listResponse = result ;
108+ setTotalCount ( ) ;
109+ }
110+
111+ if ( listResponse . length > 0 ) {
112+ setData ( ( prev ) => [ ...prev , ...listResponse ] ) ;
81113 } else {
82- setDisabledMore ( true ) ;
114+ isDisabledMoreRef . current = true ;
83115 }
84116 } catch ( e ) {
85117 console . log ( e ) ;
86118 }
87119
88120 setTimeout ( ( ) => {
89121 isLoadingRef . current = false ;
90- } , 10 ) ;
122+ } , 50 ) ;
91123 } ;
92124
93125 useLayoutEffect ( ( ) => {
@@ -101,7 +133,7 @@ export const useInfiniteScroll = <DataItem, Args extends InfinityListArgs>({
101133 } , [ data ] ) ;
102134
103135 const onScroll = useCallback ( ( ) => {
104- if ( disabledMore || isLoadingRef . current ) {
136+ if ( isDisabledMoreRef . current || isLoadingRef . current ) {
105137 return ;
106138 }
107139
@@ -112,7 +144,7 @@ export const useInfiniteScroll = <DataItem, Args extends InfinityListArgs>({
112144 if ( scrollPositionFromBottom < SCROLL_POSITION_GAP ) {
113145 getMore ( ) . catch ( console . log ) ;
114146 }
115- } , [ disabledMore , getMore ] ) ;
147+ } , [ getMore ] ) ;
116148
117149 useEffect ( ( ) => {
118150 document . addEventListener ( 'scroll' , onScroll ) ;
@@ -126,6 +158,7 @@ export const useInfiniteScroll = <DataItem, Args extends InfinityListArgs>({
126158
127159 return {
128160 data,
161+ totalCount,
129162 isLoading : isLoading || ( data . length === 0 && isFetching ) ,
130163 isLoadingMore,
131164 refreshList : getEmptyList ,
0 commit comments