フロントエンド開発といえば。
react アプリの初期化( npm init vite@latest <アプリ名> )

RTK Query の infiniteQuery

● RTK Query の infiniteQuery

概要

build.infiniteQuery()は、エンドポイント定義時に使用するメソッドで、TypeScriptでは3つのジェネリック型引数を必要とします 1 :

build.infiniteQuery<ResultType, QueryArg, PageParam>()

ジェネリック型引数

引数 説明
ResultType 単一ページのデータ型(例: Pokemon[]
QueryArg キャッシュキーとして使用される引数の型(引数がない場合はvoid
PageParam ページを特定するためのパラメータの型(例: number, string, オブジェクト型など) 1

定義オブジェクトの必須フィールド

infiniteQueryの定義オブジェクトには、以下のフィールドが必要です 2 :

1. infiniteQueryOptions (必須)

infiniteQueryOptions: {
  initialPageParam: PageParam,        // 必須: 初回リクエストのページパラメータ
  getNextPageParam: PageParamFunction, // 必須: 次のページパラメータを計算
  getPreviousPageParam?: PageParamFunction, // オプション: 前のページパラメータを計算
  maxPages?: number                    // オプション: キャッシュに保持する最大ページ数
}

2. query または queryFn (必須)

query関数は、通常のクエリと異なり、{queryArg, pageParam}オブジェクトを受け取ります 4 :

query({ queryArg, pageParam }) {
  return `/endpoint?page=${pageParam}`
}

PageParamFunction の型定義

getNextPageParamgetPreviousPageParamの関数シグネチャ 6 :

type PageParamFunction<DataType, PageParam, QueryArg> = (
  currentPage: DataType,      // 現在のページデータ
  allPages: DataType[],       // 全ページのデータ配列
  currentPageParam: PageParam, // 現在のページパラメータ
  allPageParams: PageParam[], // 全ページパラメータ配列
  queryArg: QueryArg,         // クエリ引数
) => PageParam | undefined | null

次のページがない場合はundefinedを返します 7

実装例 8

const pokemonApi = createApi({
  baseQuery: fetchBaseQuery({ baseUrl: 'https://example.com' }),
  endpoints: (build) => ({
    getInfinitePokemon: build.infiniteQuery<Pokemon[], string, number>({
      infiniteQueryOptions: {
        initialPageParam: 0,
        maxPages: 3,
        getNextPageParam: (lastPage, allPages, lastPageParam) =>
          lastPageParam + 1,
        getPreviousPageParam: (firstPage, allPages, firstPageParam) => {
          return firstPageParam > 0 ? firstPageParam - 1 : undefined
        },
      },
      query({ pageParam }) {
        return `https://example.com/listItems?page=${pageParam}`
      },
    }),
  }),
})

Notes

  • infiniteQueryOptionsinitialPageParamgetNextPageParamは必須です 9
  • 通常のクエリエンドポイントと同様に、transformResponseprovidesTagsonCacheEntryAddedなどのオプションも使用できます 10
  • query関数は{queryArg, pageParam}を受け取る点が通常のクエリと異なります 11

Wiki pages you might want to explore:

Citations

File: docs/rtk-query/usage/infinite-queries.mdx (L34-34)

- However, there is a separation between the "query arg" used for the cache key, and the "page param" used to fetch a specific page. Since both are useful for determining what to fetch, **your `query` and `queryFn` methods will receive a combined object with `{queryArg, pageParam}` as the first argument, instead of just the `queryArg` by itself**.

File: docs/rtk-query/usage/infinite-queries.mdx (L64-64)

Infinite query endpoints are defined by returning an object inside the `endpoints` section of `createApi`, and defining the fields using the `build.infiniteQuery()` method. They are an extension of standard query endpoints - you can specify [the same options as standard queries](./queries.mdx#defining-query-endpoints) (providing either `query` or `queryFn`, customizing with `transformResponse`, lifecycles with `onCacheEntryAdded` and `onQueryStarted`, defining tags, etc). However, they also require an additional `infiniteQueryOptions` field to specify the infinite query behavior.

File: docs/rtk-query/usage/infinite-queries.mdx (L66-66)

With TypeScript, you must supply 3 generic arguments: `build.infiniteQuery<ResultType, QueryArg, PageParam>`, where `ResultType` is the contents of a single page, `QueryArg` is the type passed in as the cache key, and `PageParam` is the value used to request a specific page. If there is no argument, use `void` for the arg type instead.

File: docs/rtk-query/usage/infinite-queries.mdx (L68-78)

### `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.

Both `initialPageParam` and `getNextPageParam` are required, to
ensure the infinite query can properly fetch the next page of data. Also, `initialPageParam` may be specified when using the endpoint, to override the default value for a first fetch. `maxPages` and `getPreviousPageParam` are both optional.

File: docs/rtk-query/usage/infinite-queries.mdx (L84-92)

```ts
export type PageParamFunction<DataType, PageParam, QueryArg> = (
  currentPage: DataType,
  allPages: DataType[],
  currentPageParam: PageParam,
  allPageParams: PageParam[],
  queryArg: QueryArg,
) => PageParam | undefined | null

**File:** docs/rtk-query/usage/infinite-queries.mdx (L102-102)
```text
If there is no possible page to fetch in that direction, the callback should return `undefined`.

File: packages/toolkit/src/query/endpointDefinitions.ts (L887-948)

    CacheCollectionQueryExtraOptions {
  type: DefinitionType.infinitequery

  providesTags?: ResultDescription<
    TagTypes,
    InfiniteData<ResultType, PageParam>,
    QueryArg,
    BaseQueryError<BaseQuery>,
    BaseQueryMeta<BaseQuery>
  >
  /**
   * Not to be used. A query should not invalidate tags in the cache.
   */
  invalidatesTags?: never

  /**
   * 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.
   * `maxPages` and `getPreviousPageParam` are both optional.
   * 
   * @example
   * 
   * ```ts
   * // codeblock-meta title="infiniteQueryOptions example"
   * import { createApi, fetchBaseQuery, defaultSerializeQueryArgs } from '@reduxjs/toolkit/query/react'
   * 
   * type Pokemon = {
   *   id: string
   *   name: string
   * }
   * 
   * const pokemonApi = createApi({
   *   baseQuery: fetchBaseQuery({ baseUrl: 'https://pokeapi.co/api/v2/' }),
   *   endpoints: (build) => ({
   *     getInfinitePokemonWithMax: build.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<

File: docs/rtk-query/api/createApi.mdx (L271-271)

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.

File: docs/rtk-query/api/createApi.mdx (L282-285)

type InfiniteQueryCombinedArg<QueryArg, PageParam> = {
  queryArg: QueryArg
  pageParam: PageParam
}

File: docs/rtk-query/api/createApi.mdx (L306-309)

     * `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.
No.2663
10/13 10:00

edit