useInfiniteQuery 사용시 API Call이 2번씩 되는 문제점이 있었다.
하지만 파악을 해보니 props로 함수를 넘길때 리렌더링이 발생한 문제였다.
해결한 방법을 기억하기위해 이 글을 작성한다. 😁
useInfiniteQuery로 구현한 무한스크롤이 스크롤을 내려 새 페이지를 호출 할때 API가 두번씩 호출되었다.
v4와 v5의 공식문서를 비교해보니, v5에서는 undefined | null로 바뀌어있었고, Tanstack Query의 구현부분에서도 undefined | null로 되어있는것을 확인했다.
type GetNextPageParamFunction<TPageParam, TQueryFnData = unknown> =
(lastPage: TQueryFnData,
allPages: Array<TQueryFnData>,
lastPageParam: TPageParam,
allPageParams: Array<TPageParam>) => TPageParam | undefined | null;
null을 넣었을때는 fetch가 되지 않으므로, 이 문제점은 아니였다.
여기서 문제가 발생하였다.
<DataTable
data={asDefects}
getNextPage={() => {
if (hasNextPage) {
fetchNextPage();
}
}}
/>
props
로 함수를 넣어주고 있었는데 이 부분에서 문제가 발생하였다.
리액트에서는 함수를 props
로 넘길때 불필요한 리렌더링이 발생된다.
왜냐하면 리액트는 부모컴포넌트가 리렌더링되면 자식 컴포넌트는 무조건 리렌더링이 발생한다.
컴포넌트가 리렌더링되면 함수도 새로 만들어진다.
이 부분을 간과하고있어서 문제가 발생하고 있었다.
따라서 getNextPage
에 들어갈 함수를 useCallback
을 통해 처리하였다.
const getNextPage = useCallback(() => {
if (hasNextPage) {
fetchNextPage();
}
}, [hasNextPage, fetchNextPage]);
정상적으로 2번의 API call이 한번으로 해결되었다.