Skip to content

Commit

Permalink
Add infinite query endpoint docs
Browse files Browse the repository at this point in the history
  • Loading branch information
markerikson committed Jan 17, 2025
1 parent 1bc4afd commit 62b4cad
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 5 deletions.
83 changes: 82 additions & 1 deletion docs/rtk-query/api/createApi.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,10 @@ See [Endpoint Definition Parameters](#endpoint-definition-parameters) for detail
#### Query endpoint definition
Query endpoints (defined with `builder.query()`) are used to cache data fetched from the server.
You must specify either a `query` field (which will use the API's `baseQuery` to make a request), or a `queryFn` function with your own async logic. All other fields are optional.
```ts title="Query endpoint definition" no-transpile
export type QueryDefinition<
QueryArg,
Expand Down Expand Up @@ -220,8 +224,70 @@ export type QueryDefinition<
}
```
#### Infinite Query endpoint definition
Infinite query endpoints (defined with `builder.infiniteQuery()`) are used to cache multi-page data sets from the server. They have all the same callbacks and options as standard query endpoints, but also require an additional [`infiniteQueryOptions`](#infinitequeryoptions) field to specify how to calculate the unique parameters to fetch each page.
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"` as the query arg, but use a page number as the param to determine which page to fetch out of the results. This means the page param is what will be passed to your `query` or `queryFn` methods.
```ts title="Infinite Query endpoint definition" no-transpile
export type PageParamFunction<DataType, PageParam> = (
firstPage: DataType,
allPages: Array<DataType>,
firstPageParam: PageParam,
allPageParams: Array<PageParam>,
) => PageParam | undefined | null

export type InfiniteQueryDefinition<
QueryArg,
PageParam,
BaseQuery extends BaseQueryFn,
TagTypes extends string,
ResultType,
ReducerPath extends string = string,
> =
// Infinite queries have all the same options as query endpoints,
// but store the `{data, pages}` structure, and use the
// `PageParam` type as the `QueryArg` for fetching.
QueryDefinition<PageParam, BaseQuery, TagTypes, InfiniteData<ResultType>> & {
/**
* Required options to configure the infinite query behavior.
* `initialPageParam` and `getNextPageParam` are required, to
* ensure the infinite query can properly fetch the next page of data.
* `initialPageparam` may be specified when using the
* endpoint, to override the default value.
*/
infiniteQueryOptions: {
/**
* The initial page parameter to use for the first page fetch.
*/
initialPageParam: PageParam
/**
* If specified, only keep this many pages in cache at once.
* If additional pages are fetched, older pages in the other
* direction will be dropped from the cache.
*/
maxPages?: number
/**
* This function can be set to automatically get the previous cursor for infinite queries.
* The result will also be used to determine the value of `hasPreviousPage`.
*/
getPreviousPageParam?: PageParamFunction<DataType, PageParam>
/**
* This function is required to automatically get the next cursor for infinite queries.
* The result will also be used to determine the value of `hasNextPage`.
*/
getNextPageParam: PageParamFunction<DataType, PageParam>
}
}
```
#### Mutation endpoint definition
Mutation endpoints (defined with `builder.mutation()`) are used to send updates to the server, and force invalidation and refetching of query endpoints.
As with queries, you must specify either the `query` option or the `queryFn` async method.
```ts title="Mutation endpoint definition" no-transpile
export type MutationDefinition<
QueryArg,
Expand Down Expand Up @@ -446,7 +512,7 @@ export interface BaseQueryApi {
}
```

#### queryFn function arguments
#### `queryFn` function arguments

- `args` - The argument provided when the query itself is called
- `api` - The `BaseQueryApi` object, containing `signal`, `dispatch` and `getState` properties
Expand All @@ -458,6 +524,21 @@ export interface BaseQueryApi {

[examples](docblock://query/endpointDefinitions.ts?token=EndpointDefinitionWithQueryFn.queryFn)

### `infiniteQueryOptions`

_(only for `infiniteQuery` endpoints)_

[summary](docblock://query/endpointDefinitions.ts?token=InfiniteQueryExtraOptions.infiniteQueryOptions)

The `infiniteQueryOptions` field includes:

- `initialPageParam`: the default page param value used for the first request, if this was not specified at the usage site
- `maxPages`: an optional limit to how many fetched pages will be kept in the cache entry at a time
- `getNextPageParam`: a required callback you must provide to calculate the next page param, given the existing cached pages and page params
- `getPreviousPageParam`: an optional callback that will be used to calculate the previous page param, if you try to fetch backwards.

[examples](docblock://query/endpointDefinitions.ts?token=InfiniteQueryExtraOptions.infiniteQueryOptions)

### `transformResponse`

_(optional, not applicable with `queryFn`)_
Expand Down
2 changes: 1 addition & 1 deletion packages/toolkit/src/query/createApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export interface CreateApiOptions<
*/
serializeQueryArgs?: SerializeQueryArgs<unknown>
/**
* Endpoints are a set of operations that you want to perform against your server. You define them as an object using the builder syntax. There are two basic endpoint types: [`query`](../../rtk-query/usage/queries) and [`mutation`](../../rtk-query/usage/mutations).
* Endpoints are a set of operations that you want to perform against your server. You define them as an object using the builder syntax. There are three endpoint types: [`query`](../../rtk-query/usage/queries), [`infiniteQuery`](../../rtk-query/usage/infinite-queries) and [`mutation`](../../rtk-query/usage/mutations).
*/
endpoints(
build: EndpointBuilder<BaseQuery, TagTypes, ReducerPath>,
Expand Down
38 changes: 36 additions & 2 deletions packages/toolkit/src/query/endpointDefinitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -604,8 +604,42 @@ export interface InfiniteQueryExtraOptions<
/**
* Required options to configure the infinite query behavior.
* `initialPageParam` and `getNextPageParam` are required, to
* ensure the infinite query can properly fetch the next page of data. `initialPageparam` may be specified when using the
* ensure the infinite query can properly fetch the next page of data.
* `initialPageParam` may be specified when using the
* endpoint, to override the default value.
*
* @example
*
* ```ts
* // codeblock-meta title="infiniteQueryOptions example"
* getInfinitePokemonWithMax: builder.infiniteQuery<
Pokemon[],
string,
number
>({
infiniteQueryOptions: {
initialPageParam: 0,
maxPages: 3,
getNextPageParam: (
lastPage,
allPages,
lastPageParam,
allPageParams,
) => lastPageParam + 1,
getPreviousPageParam: (
firstPage,
allPages,
firstPageParam,
allPageParams,
) => {
return firstPageParam > 0 ? firstPageParam - 1 : undefined
},
},
query(pageParam) {
return `https://example.com/listItems?page=${pageParam}`
},
}),
* ```
*/
infiniteQueryOptions: InfiniteQueryConfigOptions<ResultType, PageParam>

Expand Down Expand Up @@ -691,7 +725,7 @@ export type InfiniteQueryDefinition<
ResultType,
ReducerPath extends string = string,
> =
// Intentionally use `PageParam` as the QueryArg` type
// Intentionally use `PageParam` as the `QueryArg` type
BaseEndpointDefinition<PageParam, BaseQuery, ResultType> &
InfiniteQueryExtraOptions<
TagTypes,
Expand Down
2 changes: 1 addition & 1 deletion packages/toolkit/src/query/react/buildHooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ import { useStableQueryArgs } from './useSerializedStableValue'
import { useShallowStableValue } from './useShallowStableValue'
import type { InfiniteQueryDirection } from '../core/apiState'
import { isInfiniteQueryDefinition } from '../endpointDefinitions'
import { StartInfiniteQueryActionCreator } from '../core/buildInitiate'
import type { StartInfiniteQueryActionCreator } from '../core/buildInitiate'

// Copy-pasted from React-Redux
const canUseDOM = () =>
Expand Down

0 comments on commit 62b4cad

Please sign in to comment.