@@ -16,43 +16,49 @@ import type {
16
16
export const useInfiniteDataLoader = <
17
17
ResultType = unknown ,
18
18
ErrorType extends Error = Error ,
19
- ParamsType = unknown ,
19
+ ParamsType extends Record < string , unknown > = Record < string , unknown > ,
20
20
ParamsPageKey extends keyof ParamsType = keyof ParamsType ,
21
21
> (
22
22
baseKey : KeyType ,
23
- method : ( params ?: ParamsType ) => PromiseType < ResultType > ,
23
+ method : ( params : ParamsType ) => PromiseType < ResultType > ,
24
+ baseParams : ParamsType ,
25
+ pageParamKey : ParamsPageKey ,
24
26
config ?: UseInfiniteDataLoaderConfig <
25
27
ResultType ,
26
28
ErrorType ,
27
29
ParamsType ,
28
30
ParamsPageKey
29
31
> ,
30
32
) : UseInfiniteDataLoaderResult < ResultType , ErrorType > => {
31
- const { getOrAddRequest, onError : onGlobalError } = useDataLoaderContext ( )
33
+ const {
34
+ getOrAddRequest,
35
+ computeKey,
36
+ onError : onGlobalError ,
37
+ } = useDataLoaderContext ( )
32
38
const {
33
39
enabled = true ,
34
40
onError,
35
41
onSuccess,
36
42
keepPreviousData = false ,
37
43
initialData,
38
44
dataLifetime,
39
- pageKey,
40
- params,
41
45
getNextPage,
42
46
} = config ?? { }
43
47
const requestRefs = useRef < DataLoader < ResultType , ErrorType > [ ] > ( [ ] )
44
- const [ page , setPage ] = useState (
45
- params && pageKey ? params [ pageKey ] : undefined ,
46
- )
48
+ const [ page , setPage ] = useState ( baseParams [ pageParamKey ] )
47
49
const nextPageRef = useRef ( page )
48
50
const getNextPageRef = useRef ( getNextPage )
49
51
const methodRef = useRef ( ( ) =>
50
52
method (
51
- pageKey && page ? ( { ...params , [ pageKey ] : page } as ParamsType ) : params ,
53
+ pageParamKey && page
54
+ ? ( { ...baseParams , [ pageParamKey ] : page } as ParamsType )
55
+ : baseParams ,
52
56
) ,
53
57
)
54
58
const paramsRef = useRef (
55
- pageKey && page ? ( { ...params , [ pageKey ] : page } as ParamsType ) : params ,
59
+ pageParamKey && page
60
+ ? ( { ...baseParams , [ pageParamKey ] : page } as ParamsType )
61
+ : baseParams ,
56
62
)
57
63
const onSuccessRef = useRef ( onSuccess )
58
64
const onErrorRef = useRef ( onError ?? onGlobalError )
@@ -62,30 +68,36 @@ export const useInfiniteDataLoader = <
62
68
setCounter ( current => current + 1 )
63
69
} , [ ] )
64
70
65
- const baseQueryKey = useMemo (
66
- ( ) => marshalQueryKey ( [ marshalQueryKey ( baseKey ) , page as string | number ] ) ,
67
- [ baseKey , page ] ,
68
- )
69
-
70
- useEffect ( ( ) => {
71
- requestRefs . current . forEach ( request => request . removeObserver ( ( ) => null ) )
72
- requestRefs . current = [ ]
73
- forceRerender ( )
74
- } , [ baseKey , forceRerender ] )
71
+ const baseQueryKey = useMemo ( ( ) => marshalQueryKey ( baseKey ) , [ baseKey ] )
75
72
76
73
useEffect (
77
74
( ) => ( ) => {
78
- requestRefs . current . forEach ( request => request . removeObserver ( ( ) => null ) )
75
+ requestRefs . current . forEach ( request =>
76
+ request . removeObserver ( forceRerender ) ,
77
+ )
79
78
} ,
80
- [ ] ,
79
+ [ forceRerender ] ,
81
80
)
82
81
83
- const getCurrentRequest = useCallback ( ( ) => {
84
- const requestInRef = requestRefs . current . find (
85
- request => request . key === baseQueryKey ,
82
+ const getCurrentRequest = ( ) => {
83
+ const currentQueryKey = marshalQueryKey ( [
84
+ baseQueryKey ,
85
+ 'infinite' ,
86
+ page as string | number ,
87
+ ] )
88
+ requestRefs . current . forEach ( request =>
89
+ ! request . key . startsWith ( computeKey ( baseQueryKey ) )
90
+ ? request . removeObserver ( forceRerender )
91
+ : undefined ,
92
+ )
93
+ requestRefs . current = requestRefs . current . filter ( ( { key } ) =>
94
+ key . startsWith ( computeKey ( baseQueryKey ) ) ,
95
+ )
96
+ const requestInRef = requestRefs . current . find ( request =>
97
+ request . key . endsWith ( currentQueryKey ) ,
86
98
)
87
99
if ( ! requestInRef ) {
88
- const request = getOrAddRequest < ResultType , ErrorType > ( baseQueryKey , {
100
+ const request = getOrAddRequest < ResultType , ErrorType > ( currentQueryKey , {
89
101
enabled,
90
102
method : methodRef . current ,
91
103
} )
@@ -96,7 +108,7 @@ export const useInfiniteDataLoader = <
96
108
}
97
109
98
110
return requestInRef
99
- } , [ baseQueryKey , forceRerender , enabled , getOrAddRequest ] )
111
+ }
100
112
101
113
const request = getCurrentRequest ( )
102
114
@@ -166,8 +178,10 @@ export const useInfiniteDataLoader = <
166
178
167
179
useEffect ( ( ) => {
168
180
paramsRef . current =
169
- pageKey && page ? ( { ...params , [ pageKey ] : page } as ParamsType ) : params
170
- } , [ params , pageKey , page ] )
181
+ pageParamKey && page
182
+ ? ( { ...baseParams , [ pageParamKey ] : page } as ParamsType )
183
+ : baseParams
184
+ } , [ baseParams , pageParamKey , page ] )
171
185
172
186
useEffect ( ( ) => {
173
187
if ( needLoad ) {
@@ -180,6 +194,7 @@ export const useInfiniteDataLoader = <
180
194
if ( getNextPageRef . current ) {
181
195
nextPageRef . current = getNextPageRef . current (
182
196
result ,
197
+ paramsRef . current ,
183
198
) as typeof nextPageRef . current
184
199
}
185
200
await onSuccessLoad ( result )
@@ -203,16 +218,18 @@ export const useInfiniteDataLoader = <
203
218
isLoadingFirstPage,
204
219
data :
205
220
isLoadingFirstPage ||
206
- requestRefs . current . filter ( dataloader => ! ! dataloader . data ) . length === 0
221
+ [ ...requestRefs . current ] . filter ( dataloader => ! ! dataloader . data )
222
+ . length === 0
207
223
? initialData
208
- : ( requestRefs . current
224
+ : ( [ ... requestRefs . current ]
209
225
. filter ( dataloader => ! ! dataloader . data )
210
226
. map ( dataloader => dataloader . data ) as ResultType [ ] ) ,
211
227
error : request . error ,
212
228
reload,
213
229
loadMore,
214
230
} ) ,
215
231
[
232
+ initialData ,
216
233
isIdle ,
217
234
isLoading ,
218
235
isSuccess ,
@@ -221,7 +238,6 @@ export const useInfiniteDataLoader = <
221
238
isLoadingFirstPage ,
222
239
reload ,
223
240
loadMore ,
224
- initialData ,
225
241
] ,
226
242
)
227
243
0 commit comments