[React] props로 함수를 넘길때 리렌더링 막기

임홍원·2024년 7월 2일
0
post-thumbnail

useInfiniteQuery 사용시 API Call이 2번씩 되는 문제점이 있었다.
하지만 파악을 해보니 props로 함수를 넘길때 리렌더링이 발생한 문제였다.
해결한 방법을 기억하기위해 이 글을 작성한다. 😁

문제상황

useInfiniteQuery로 구현한 무한스크롤이 스크롤을 내려 새 페이지를 호출 할때 API가 두번씩 호출되었다.

생각해본 의문점들

1. useInfiniteQuery 사용시 getNextPageParam이 없으면 null을 넣기

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가 되지 않으므로, 이 문제점은 아니였다.

2. React의 리렌더링 문제

여기서 문제가 발생하였다.

<DataTable
data={asDefects}
getNextPage={() => {
  if (hasNextPage) {
    fetchNextPage();
  }
}}
/>

props 로 함수를 넣어주고 있었는데 이 부분에서 문제가 발생하였다.
리액트에서는 함수를 props 로 넘길때 불필요한 리렌더링이 발생된다.
왜냐하면 리액트는 부모컴포넌트가 리렌더링되면 자식 컴포넌트는 무조건 리렌더링이 발생한다.
컴포넌트가 리렌더링되면 함수도 새로 만들어진다.
이 부분을 간과하고있어서 문제가 발생하고 있었다.

따라서 getNextPage 에 들어갈 함수를 useCallback 을 통해 처리하였다.

const getNextPage = useCallback(() => {
  if (hasNextPage) {
    fetchNextPage();
  }
}, [hasNextPage, fetchNextPage]);

정상적으로 2번의 API call이 한번으로 해결되었다.

0개의 댓글

관련 채용 정보