Docs
API REFERENCES
useQueries

useQueries

useQueries hook은 여러 개의 query를 동시에 가져오는 데 사용할 수 있습니다:

const ids = [1, 2, 3];
const results = useQueries({
  queries: ids.map((id) => ({
    queryKey: ["post", id],
    queryFn: () => fetchPost(id),
    staleTime: Infinity,
  })),
});

Options

useQueries hook은 queries라는 키를 가진 옵션 객체를 받습니다. 이 queries 키의 값은 useQuery hook과 동일한 query 옵션 객체의 배열입니다 (단, queryClient 옵션은 제외됩니다 - QueryClient는 상위 레벨에서 전달할 수 있습니다).

  • queryClient?: QueryClient
    • 커스텀 QueryClient를 제공할 때 사용합니다. 그렇지 않으면 가장 가까운 컨텍스트의 QueryClient가 사용됩니다.
  • combine?: (result: UseQueriesResults) => TCombinedResult
    • 쿼리 결과를 하나의 값으로 결합할 때 사용합니다.

쿼리 객체 배열에 같은 query key가 여러 번 포함되면 쿼리 간에 데이터가 공유될 수 있습니다. 이를 피하려면 쿼리를 중복 제거하고 결과를 원하는 구조로 다시 매핑하는 것이 좋습니다.

placeholderData

useQueries에도 placeholderData 옵션이 있지만, 이전에 렌더링된 쿼리에서 정보를 전달받지 않습니다. 이는 useQueries의 입력이 매 렌더링마다 다른 수의 쿼리일 수 있기 때문입니다.

Returns

useQueries hook은 모든 쿼리 결과를 포함하는 배열을 반환합니다. 반환된 배열의 순서는 입력된 순서와 같습니다.

Combine

쿼리 결과의 data (또는 다른 쿼리 정보)를 하나의 값으로 결합하고 싶다면 combine 옵션을 사용할 수 있습니다. 결과는 가능한 한 참조 안정성을 유지하며 구조적으로 공유됩니다.

const ids = [1, 2, 3];
const combinedQueries = useQueries({
  queries: ids.map((id) => ({
    queryKey: ["post", id],
    queryFn: () => fetchPost(id),
  })),
  combine: (results) => {
    return {
      data: results.map((result) => result.data),
      pending: results.some((result) => result.isPending),
    };
  },
});

위 예제에서 combinedQueriesdatapending 속성을 가진 객체가 됩니다. 모든 다른 쿼리 결과의 속성은 사라집니다.

Memoization

combine 함수는 다음 경우에만 다시 실행됩니다:

  • combine 함수 자체의 참조가 변경된 경우
  • 쿼리 결과 중 하나라도 변경된 경우

즉, 위에서 보듯이 인라인 combine 함수는 매 렌더링 시 실행됩니다. 이를 피하려면 combine 함수를 useCallback으로 감싸거나, 의존성이 없는 경우 안정적인 함수 참조로 추출하는 것이 좋습니다.