suspense를 지원하게 된 useQueries

dante Yoon·2022년 11월 13일
22

별 건 아니지만

목록 보기
9/11

Disclaimer

본 포스팅은 tanstack/query v4.5.0을 기준으로 작성되었습니다.

useQueries 이슈

안녕하세요, 단테입니다.
react query #1523 이슈가 수정되었습니다.

이 이슈는 parallel fetch를 가능하게 하는 useQueries가 suspense mode에서는 동작하지 않는 문제점을 제보한 것입니다.

useQuery + Suspense 이슈

단일 컴포넌트에서 여러 개의 useQuery 사용 시 개발자는 아래와 같이 parallel fetching을 기대하고 코드를 작성합니다.

const issues = useQuery({ queryKey: ['issues'], queryFn: fetchIssues })
const posts = useQuery({ queryKey: ['posts'], queryFn: fetchPosts })
const comments = useQuery({ queryKey: ['comments'], queryFn: fetchComments })

하지만 Suspense와 함께 사용 시 실제로는 이렇게 동작하지 않습니다.
useQuery + suspense mode 사용 시 아래와 같이 water fall이 발생합니다.

이렇게 water fall이 발생하는 이유는
Promise가 throw 될 때 마다 해당 Promise를 반환하는 코드 다음 줄이 런타임에서 실행되기 이전에
컴포넌트가 언마운트되기 때문입니다.

useQueries

여러 개의 query를 병렬로 실행시킬 수 있게 해주는 useQueries는 Suspense와 함께 사용 시 정상적으로 동작하지 않는 이슈가 있는데 이번 v4.5.0 패치에 해당 사항이 수정되었습니다.

const results =   useQueries({queries: [
   {queryKey: ["posts"], queryFn: () => fetch("/posts") , suspense: true},
  {queryKey: ["comments"], queryFn: () => fetch("/comments"), suspense:true},
  {queryKey: ["issues"], queryFn: () => fetch("/issues"), suspense:true }
]})

useQuery + prefetch

지난 달 22일, 메인 테이너 TkDodo의 블로그를 보면 기존에 waterfall 문제를 해결하는 몇 가지 방법에 대해 말해주고 있는데요, 대표적으로 컴포넌트에 필요한 데이터 호출을 컴포넌트 렌더링 시점이 아닌 모듈 다운로드 이후에 하는 것입니다. module loading 이라고 부르기도 합니다.
번들링 파일이 실행되는 시점에 맞춰 컴포넌트 렌더링 시점과 무관하게 호출합니다.
더 일찍 호출할 수록 더 일찍 렌더링할 수 있다. 라는 아이디어를 구현한 것입니다.

const issuesQuery = { queryKey: ['issues'], queryFn: fetchIssues }

// ⬇️ initiate a fetch before the component renders
queryClient.prefetchQuery(issuesQuery)

function Issues() {
  const issues = useQuery(issuesQuery)
}

컴포넌트 외부에서 prefetch 하는 것은 데이터 호출에 있어서 이득을 가져주나 컴포넌트 내부에서만 조회할 수 있는 context를 이용할 수 없다는 단점을 가지고 있습니다.

useQueries를 사용하면 컴포넌트 내부 콘텍스트를 이용해 병렬적으로 api를 호출할 수 있어서 콘텍스트 사용을 위한 부차적인 구현을 하지 않아도 된다는 장점이 있습니다.

글을 마치며

기존에 water fall 문제를 무시하시고 useQuery와 Suspense를 사용하시던 분들은 버전 업데이트 및 useQueries 사용으로 코드를 변환하시는 것을 권장합니다.

감사합니다!

profile
성장을 향한 작은 몸부림의 흔적들

4개의 댓글

comment-user-thumbnail
2022년 11월 13일

이번 포스팅도 읽으면서 많이 배워갑니다
중간에 useQuery + prefetch 케이스에사
컴포넌트 내부에서만 조회할수 있는 context를 이용할 수없다는 단점이 있다고 하셨는데
이게 구체적으로 어떤건지 알수 있을까요?

1개의 답글
comment-user-thumbnail
2022년 11월 13일

와... 드디어 useQueries에 suspense가 지원되는군요!!
https://happysisyphe.tistory.com/54 useQuery의 네트워크 워터폴 현상에 대해서 글을 썼었는데,, 업데이트 시켜야겠네요~~

1개의 답글