리액트

useInfiniteQuery의 pageParam 와 initialPageParam의 차이

두캔두잇 2024. 12. 22. 02:32

무한스크롤 기능을 구현하면서 문제가 있었던 부분을 남겨보려고 한다.

우선 tanstack-query 공식문서에서 설명하는 useInfiniteQuery의 사용법은 위와 같다.

그리고 나서 내가 구현하려고 했던 코드를 적어보면 아래와 같다.

    export const productQuery = {
        useGets : function() {
            return useInfiniteQuery<IProductPublicFindListResponse<IApiResponse[]>, Error>({
              queryKey: ["products"],
              queryFn: ({ pageParam = 1 }) => productApi.gets(String(pageParam)),
              getNextPageParam: (lastPage) => {
                const currentPage = lastPage.meta.currentPage;
                   const totalPage = lastPage.meta.totalPage;
                   return currentPage! < totalPage! ? currentPage! + 1 : undefined;
      },
        }
    }

위의 코드를 보면 공식문서에서 제공한대로 사용했다라고 생각해서 오류가 안날줄 알았는데 오류가 발생했다.
오류의 메세지는 아래와 같다.

  • No overload matches this call.
    Overload 1 of 3, '(options: DefinedInitialDataInfiniteOptions<IProductPublicFindListResponse<IApiResponse[]>, Error, InfiniteData<IProductPublicFindListResponse<IApiResponse[]>, unknown>, QueryKey, unknown>, queryClient?: QueryClient | undefined): DefinedUseInfiniteQueryResult<...>', gave the following error.
    Argument of type '{ queryKey: string[]; queryFn: ({ pageParam }: { queryKey: QueryKey; signal: AbortSignal; pageParam: unknown; direction: FetchDirection; meta: Record<string, unknown> | undefined; }) => Promise<...>; getNextPageParam: (lastPage: IProductPublicFindListResponse<...>) => number | undefined; }' is not assignable to parameter of type 'DefinedInitialDataInfiniteOptions<IProductPublicFindListResponse<IApiResponse[]>, Error, InfiniteData<IProductPublicFindListResponse<IApiResponse[]>, unknown>, QueryKey, unknown>'.
    Property 'initialPageParam' is missing in type '{ queryKey: string[]; queryFn: ({ pageParam }: { queryKey: QueryKey; signal: AbortSignal; pageParam: unknown; direction: FetchDirection; meta: Record<string, unknown> | undefined; }) => Promise<...>; getNextPageParam: (lastPage: IProductPublicFindListResponse<...>) => number | undefined; }' but required in type 'UseInfiniteQueryOptions<IProductPublicFindListResponse<IApiResponse[]>, Error, InfiniteData<IProductPublicFindListResponse<IApiResponse[]>, unknown>, IProductPublicFindListResponse<...>, QueryKey, unknown>'.
    Overload 2 of 3, '(options: UndefinedInitialDataInfiniteOptions<IProductPublicFindListResponse<IApiResponse[]>, Error, InfiniteData<IProductPublicFindListResponse<IApiResponse[]>, unknown>, QueryKey, unknown>, queryClient?: QueryClient | undefined): UseInfiniteQueryResult<...>', gave the following error.
    Argument of type '{ queryKey: string[]; queryFn: ({ pageParam }: { queryKey: QueryKey; signal: AbortSignal; pageParam: unknown; direction: FetchDirection; meta: Record<string, unknown> | undefined; }) => Promise<...>; getNextPageParam: (lastPage: IProductPublicFindListResponse<...>) => number | undefined; }' is not assignable to parameter of type 'UndefinedInitialDataInfiniteOptions<IProductPublicFindListResponse<IApiResponse[]>, Error, InfiniteData<IProductPublicFindListResponse<IApiResponse[]>, unknown>, QueryKey, unknown>'.
    Property 'initialPageParam' is missing in type '{ queryKey: string[]; queryFn: ({ pageParam }: { queryKey: QueryKey; signal: AbortSignal; pageParam: unknown; direction: FetchDirection; meta: Record<string, unknown> | undefined; }) => Promise<...>; getNextPageParam: (lastPage: IProductPublicFindListResponse<...>) => number | undefined; }' but required in type 'UseInfiniteQueryOptions<IProductPublicFindListResponse<IApiResponse[]>, Error, InfiniteData<IProductPublicFindListResponse<IApiResponse[]>, unknown>, IProductPublicFindListResponse<...>, QueryKey, unknown>'.
    Overload 3 of 3, '(options: UseInfiniteQueryOptions<IProductPublicFindListResponse<IApiResponse[]>, Error, InfiniteData<IProductPublicFindListResponse<IApiResponse[]>, unknown>, IProductPublicFindListResponse<...>, QueryKey, unknown>, queryClient?: QueryClient | undefined): UseInfiniteQueryResult<...>', gave the following error.
    Argument of type '{ queryKey: string[]; queryFn: ({ pageParam }: { queryKey: QueryKey; signal: AbortSignal; pageParam: unknown; direction: FetchDirection; meta: Record<string, unknown> | undefined; }) => Promise<...>; getNextPageParam: (lastPage: IProductPublicFindListResponse<...>) => number | undefined; }' is not assignable to parameter of type 'UseInfiniteQueryOptions<IProductPublicFindListResponse<IApiResponse[]>, Error, InfiniteData<IProductPublicFindListResponse<IApiResponse[]>, unknown>, IProductPublicFindListResponse<...>, QueryKey, unknown>'.
    Property 'initialPageParam' is missing in type '{ queryKey: string[]; queryFn: ({ pageParam }: { queryKey: QueryKey; signal: AbortSignal; pageParam: unknown; direction: FetchDirection; meta: Record<string, unknown> | undefined; }) => Promise<...>; getNextPageParam: (lastPage: IProductPublicFindListResponse<...>) => number | undefined; }' but required in type 'UseInfiniteQueryOptions<IProductPublicFindListResponse<IApiResponse[]>, Error, InfiniteData<IProductPublicFindListResponse<IApiResponse[]>, unknown>, IProductPublicFindListResponse<...>, QueryKey, unknown>'.

다 읽어볼 필요는 없고 핵심은

Property 'initialPageParam' is missing in type 이였다.

프로퍼티중 initialPageParam 이 없어서 오류가 발생한거였는데, 내가 이해한 바로는 queryFn에서 pageParam을 1로 줬는데 pageParam을 안줘도 되는거 아닌가? 라고 생각하였는데 이 돌은 차이점이 존재했다.

1. pageParam

우선 queryFn에서 사용하는 pageParam은 queryFn 이 호출될 때의 현재 요쳥할 페이지 번호이다.
그래서 무한스크롤을 구현할 때 사용자가 스크롤을 한다면 1에서 다음 페이지를 요청한 뒤 2로 값이 자동으로 증가하여 다음페이지를 요청하는 것이다.
정리하자면 pageParam=1 은 첫 번째 페이지의 데이터를 요청하는 것이다.

2. initialPageParam

initialPageParam은 useInfiniteQuery 가 처음 실행될 때 사용되는 초기페이지 번호이다. 이 값은 쿼리가 처음 실행될 때만 사용이 되고, 그 이후에는 pageParam이 업데이트되어 사용된다.

그러면 둘 다 첫 번째 페이지를 요청하는것이 아닌가? 라고 생각할 수 있는데 정답은 아니다.
pageParam은 각 요청이 들어올때의 현재 페이지를 관리하는 것이고 initialPageParam은 쿼리가 시작될 때의 첫 번째 페이지를 설정하는 것이다.

initialPageParam은 선택사항으로 알고있었는데 다른 블로그들을 찾아보니 initialPageParam은 필수값이라고 한다.
아직은 공식문서를 보고 바로 이해하지는 못하겠는데 그래도 공식문서를 보며 참고하고 적응해야겠다..

'리액트' 카테고리의 다른 글

React tailwindCSS image  (0) 2024.12.25
react query refetching  (0) 2024.12.23
flatMap()  (2) 2024.12.21
Docker 공부  (1) 2024.12.19
tanstackquery [useInfiniteQuery]  (0) 2024.12.19