Skip to content

Commit 68bf4b6

Browse files
authored
Add queryArg as 5th param to page param functions (#4967)
1 parent 20f4579 commit 68bf4b6

File tree

9 files changed

+63
-20
lines changed

9 files changed

+63
-20
lines changed

docs/rtk-query/api/createApi.mdx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -245,11 +245,12 @@ Infinite query endpoints (defined with `build.infiniteQuery()`) are used to cach
245245
For infinite query endpoints, there is a separation between the "query arg" used for the cache key, and the "page param" used to fetch a specific page. For example, a Pokemon API endpoint might have a string query arg like `"fire"` , but use a page number as the param to determine which page to fetch out of the results. The `query` and `queryFn` methods will receive a combined `{queryArg, pageParam}` object as the argument, rather than just the `queryArg` by itself.
246246
247247
```ts title="Infinite Query endpoint definition" no-transpile
248-
export type PageParamFunction<DataType, PageParam> = (
248+
export type PageParamFunction<DataType, PageParam, QueryArg> = (
249249
firstPage: DataType,
250250
allPages: Array<DataType>,
251251
firstPageParam: PageParam,
252252
allPageParams: Array<PageParam>,
253+
queryArg: QueryArg,
253254
) => PageParam | undefined | null
254255

255256
type InfiniteQueryCombinedArg<QueryArg, PageParam> = {
@@ -290,12 +291,12 @@ export type InfiniteQueryDefinition<
290291
* This function is required to automatically get the next cursor for infinite queries.
291292
* The result will also be used to determine the value of `hasNextPage`.
292293
*/
293-
getNextPageParam: PageParamFunction<DataType, PageParam>
294+
getNextPageParam: PageParamFunction<DataType, PageParam, QueryArg>
294295
/**
295296
* This function can be set to automatically get the previous cursor for infinite queries.
296297
* The result will also be used to determine the value of `hasPreviousPage`.
297298
*/
298-
getPreviousPageParam?: PageParamFunction<DataType, PageParam>
299+
getPreviousPageParam?: PageParamFunction<DataType, PageParam, QueryArg>
299300
/**
300301
* If specified, only keep this many pages in cache at once.
301302
* If additional pages are fetched, older pages in the other

docs/rtk-query/usage/infinite-queries.mdx

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,12 @@ ensure the infinite query can properly fetch the next page of data. Also, `initi
8282
`getNextPageParam` and `getPreviousPageParam` are user-defined, giving you flexibility to determine how those values are calculated:
8383

8484
```ts
85-
export type PageParamFunction<DataType, PageParam> = (
85+
export type PageParamFunction<DataType, PageParam, QueryArg> = (
8686
currentPage: DataType,
8787
allPages: DataType[],
8888
currentPageParam: PageParam,
8989
allPageParams: PageParam[],
90+
queryArg: QueryArg,
9091
) => PageParam | undefined | null
9192
```
9293
@@ -96,6 +97,8 @@ Since both actual page contents and page params are passed in, you can calculate
9697
9798
The "current" arguments will be either the last page for `getNextPageParam`, or the first page for `getPreviousPageParam`.
9899
100+
The list of arguments is the same as with React Query, but with the addition of `queryArg` at the end. (This is because React Query always has access to the query arg when you pass the options to its `useQuery` hook, but with RTK Query the endpoints are defined separately, so this makes the query arg accessible if you need it to calculate the page params.)
101+
99102
If there is no possible page to fetch in that direction, the callback should return `undefined`.
100103
101104
### Infinite Query Definition Example
@@ -119,14 +122,20 @@ const pokemonApi = createApi({
119122
// Optionally limit the number of cached pages
120123
maxPages: 3,
121124
// Must provide a `getNextPageParam` function
122-
getNextPageParam: (lastPage, allPages, lastPageParam, allPageParams) =>
123-
lastPageParam + 1,
125+
getNextPageParam: (
126+
lastPage,
127+
allPages,
128+
lastPageParam,
129+
allPageParams,
130+
queryArg,
131+
) => lastPageParam + 1,
124132
// Optionally provide a `getPreviousPageParam` function
125133
getPreviousPageParam: (
126134
firstPage,
127135
allPages,
128136
firstPageParam,
129137
allPageParams,
138+
queryArg,
130139
) => {
131140
return firstPageParam > 0 ? firstPageParam - 1 : undefined
132141
},

packages/toolkit/src/query/core/apiState.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,15 @@ export type RefetchConfigOptions = {
2525
refetchOnFocus: boolean
2626
}
2727

28-
export type PageParamFunction<DataType, PageParam> = (
28+
export type PageParamFunction<DataType, PageParam, QueryArg> = (
2929
firstPage: DataType,
3030
allPages: Array<DataType>,
3131
firstPageParam: PageParam,
3232
allPageParams: Array<PageParam>,
33+
queryArg: QueryArg,
3334
) => PageParam | undefined | null
3435

35-
export type InfiniteQueryConfigOptions<DataType, PageParam> = {
36+
export type InfiniteQueryConfigOptions<DataType, PageParam, QueryArg> = {
3637
/**
3738
* The initial page parameter to use for the first page fetch.
3839
*/
@@ -41,12 +42,12 @@ export type InfiniteQueryConfigOptions<DataType, PageParam> = {
4142
* This function is required to automatically get the next cursor for infinite queries.
4243
* The result will also be used to determine the value of `hasNextPage`.
4344
*/
44-
getNextPageParam: PageParamFunction<DataType, PageParam>
45+
getNextPageParam: PageParamFunction<DataType, PageParam, QueryArg>
4546
/**
4647
* This function can be set to automatically get the previous cursor for infinite queries.
4748
* The result will also be used to determine the value of `hasPreviousPage`.
4849
*/
49-
getPreviousPageParam?: PageParamFunction<DataType, PageParam>
50+
getPreviousPageParam?: PageParamFunction<DataType, PageParam, QueryArg>
5051
/**
5152
* If specified, only keep this many pages in cache at once.
5253
* If additional pages are fetched, older pages in the other

packages/toolkit/src/query/core/buildInitiate.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,13 @@ export type StartInfiniteQueryActionCreatorOptions<
7979
param?: unknown
8080
} & Partial<
8181
Pick<
82-
Partial<InfiniteQueryConfigOptions<ResultTypeFrom<D>, PageParamFrom<D>>>,
82+
Partial<
83+
InfiniteQueryConfigOptions<
84+
ResultTypeFrom<D>,
85+
PageParamFrom<D>,
86+
InfiniteQueryArgFrom<D>
87+
>
88+
>,
8389
'initialPageParam'
8490
>
8591
>

packages/toolkit/src/query/core/buildSelectors.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -291,10 +291,12 @@ export function buildSelectors<
291291
hasNextPage: getHasNextPage(
292292
infiniteQueryOptions,
293293
stateWithRequestFlags.data,
294+
stateWithRequestFlags.originalArgs,
294295
),
295296
hasPreviousPage: getHasPreviousPage(
296297
infiniteQueryOptions,
297298
stateWithRequestFlags.data,
299+
stateWithRequestFlags.originalArgs,
298300
),
299301
isFetchingNextPage: isLoading && isForward,
300302
isFetchingPreviousPage: isLoading && isBackward,
@@ -395,18 +397,20 @@ export function buildSelectors<
395397
}
396398

397399
function getHasNextPage(
398-
options: InfiniteQueryConfigOptions<any, any>,
400+
options: InfiniteQueryConfigOptions<any, any, any>,
399401
data?: InfiniteData<unknown, unknown>,
402+
queryArg?: unknown,
400403
): boolean {
401404
if (!data) return false
402-
return getNextPageParam(options, data) != null
405+
return getNextPageParam(options, data, queryArg) != null
403406
}
404407

405408
function getHasPreviousPage(
406-
options: InfiniteQueryConfigOptions<any, any>,
409+
options: InfiniteQueryConfigOptions<any, any, any>,
407410
data?: InfiniteData<unknown, unknown>,
411+
queryArg?: unknown,
408412
): boolean {
409413
if (!data || !options.getPreviousPageParam) return false
410-
return getPreviousPageParam(options, data) != null
414+
return getPreviousPageParam(options, data, queryArg) != null
411415
}
412416
}

packages/toolkit/src/query/core/buildThunks.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -699,7 +699,11 @@ export function buildThunks<
699699
if ('direction' in arg && arg.direction && existingData.pages.length) {
700700
const previous = arg.direction === 'backward'
701701
const pageParamFn = previous ? getPreviousPageParam : getNextPageParam
702-
const param = pageParamFn(infiniteQueryOptions, existingData)
702+
const param = pageParamFn(
703+
infiniteQueryOptions,
704+
existingData,
705+
arg.originalArgs,
706+
)
703707

704708
result = await fetchPage(existingData, param, maxPages, previous)
705709
} else {
@@ -731,6 +735,7 @@ export function buildThunks<
731735
const param = getNextPageParam(
732736
infiniteQueryOptions,
733737
result.data as InfiniteData<unknown, unknown>,
738+
arg.originalArgs,
734739
)
735740
result = await fetchPage(
736741
result.data as InfiniteData<unknown, unknown>,
@@ -1036,27 +1041,31 @@ In the case of an unhandled error, no tags will be "provided" or "invalidated".`
10361041
}
10371042

10381043
export function getNextPageParam(
1039-
options: InfiniteQueryConfigOptions<unknown, unknown>,
1044+
options: InfiniteQueryConfigOptions<unknown, unknown, unknown>,
10401045
{ pages, pageParams }: InfiniteData<unknown, unknown>,
1046+
queryArg: unknown,
10411047
): unknown | undefined {
10421048
const lastIndex = pages.length - 1
10431049
return options.getNextPageParam(
10441050
pages[lastIndex],
10451051
pages,
10461052
pageParams[lastIndex],
10471053
pageParams,
1054+
queryArg,
10481055
)
10491056
}
10501057

10511058
export function getPreviousPageParam(
1052-
options: InfiniteQueryConfigOptions<unknown, unknown>,
1059+
options: InfiniteQueryConfigOptions<unknown, unknown, unknown>,
10531060
{ pages, pageParams }: InfiniteData<unknown, unknown>,
1061+
queryArg: unknown,
10541062
): unknown | undefined {
10551063
return options.getPreviousPageParam?.(
10561064
pages[0],
10571065
pages,
10581066
pageParams[0],
10591067
pageParams,
1068+
queryArg,
10601069
)
10611070
}
10621071

packages/toolkit/src/query/endpointDefinitions.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -907,7 +907,11 @@ export interface InfiniteQueryExtraOptions<
907907
908908
* ```
909909
*/
910-
infiniteQueryOptions: InfiniteQueryConfigOptions<ResultType, PageParam>
910+
infiniteQueryOptions: InfiniteQueryConfigOptions<
911+
ResultType,
912+
PageParam,
913+
QueryArg
914+
>
911915

912916
/**
913917
* Can be provided to return a custom cache key value based on the query arguments.

packages/toolkit/src/query/tests/infiniteQueries.test-d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ describe('Infinite queries', () => {
2525
allPages,
2626
lastPageParam,
2727
allPageParams,
28+
queryArg,
2829
) => {
2930
expectTypeOf(lastPage).toEqualTypeOf<Pokemon[]>()
3031

@@ -34,6 +35,8 @@ describe('Infinite queries', () => {
3435

3536
expectTypeOf(allPageParams).toEqualTypeOf<number[]>()
3637

38+
expectTypeOf(queryArg).toBeString()
39+
3740
return lastPageParam + 1
3841
},
3942
},

packages/toolkit/src/query/tests/infiniteQueries.test.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,19 @@ describe('Infinite queries', () => {
3030
allPages,
3131
lastPageParam,
3232
allPageParams,
33-
) => lastPageParam + 1,
33+
queryArg,
34+
) => {
35+
expect(typeof queryArg).toBe('string')
36+
return lastPageParam + 1
37+
},
3438
getPreviousPageParam: (
3539
firstPage,
3640
allPages,
3741
firstPageParam,
3842
allPageParams,
43+
queryArg,
3944
) => {
45+
expect(typeof queryArg).toBe('string')
4046
return firstPageParam > 0 ? firstPageParam - 1 : undefined
4147
},
4248
},

0 commit comments

Comments
 (0)