애드블럭 종료 후 보실 수 있습니다.

ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • react-query useInfiniteQuery 데이터 편하게 사용하기
    Tip 2022. 8. 31. 17:45
    728x90

    (이 글은 react-query@3.19.1을 바탕으로 작성되었습니다)

    react-query를 사용할 때 useQuery만큼이나 많이 사용하는 것이 useInfiniteQuery이다.

    특정 웹 사이트의 경우 useQuery보다 많이 사용한다.

    사용 방법 자체도 무척 간편하게 되어 있어서 문서를 확인하고 사용하는데 별다른 제약이 없다.

     

    그런데 데이터가 오는 방식이 특이하다.

     

    만약 데이터를 axios로 받아왔을 때의 형식은 아래와 같다.

    {
      data: {
        posts: [...]
      }
    }

    이런 데이터 형태는 추가로 받아올 때 역시 동일하다.

    나의 경우 react-query를 사용하기 전 redux-toolkit을 사용할 때는 아래와 같은 방법을 사용했다.

    // lodash 미사용
    state.posts = [...state.posts, ...action.payload.data.posts];
    // lodash 사용
    state.posts = _.concat(state.posts, action.payload.data.posts);

    하지만 useInfiniteQuery에서 오는 데이터 형태는 조금 다르다.

    {
      pageParams: [...],
      pages: [
        {
          ...
          data: {
            posts: [...] 
          }
        },
        {
          ...
          data: {
            posts: [...] 
          }
        }
        ...
      ]
    }

    데이터가 pages라는 배열에 한 번 더 감싸인 형태로 오는 것을 확인할 수 있다.

    물론 몇 번째로 데이터를 가지고 왔는지 등을 이용해 list virtualization을 사용할 수 도 있겠지만 실제 사용할 때는 불편한 것이 사실이다.

     

    pages를 map을 돌리고 내부에서 posts로 한 번 더 map을 돌리는 방법으로 사용할 수도 있지만 아주 간단한 방법으로 평소 자주 사용했던 하나의 map을 이용하는 방법으로 수정할 수 있다.

    const { data } = useGetPosts();
    
    const posts = useMemo(
      () => data?.pages.flatMap((page) => page.data.posts,
      [data?.pages],
    );

    flatMap을 활용하면 깊이 1의 flat 함수와 map을 이용해 병합까지 해 주는 간편한 내장 함수다.

    이외에도 reduce를 이용하는 방법 등이 존재하는데 배열 자체를 flat 하게 하는 방법으로는 flatMap이 가장 직관적이고 쉽게 사용할 수 있는 방법이라고 생각한다.

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    댓글

Designed by Tistory.