본문으로 건너뛰기

종속 쿼리

useQuery 종속 Query

종속(또는 직렬) 쿼리는 실행되기 전에 이전 쿼리가 완료되기를 기다립니다. 이를 구현하려면 enabled 옵션을 사용하여 쿼리가 언제 실행할 준비가 되었는지 알려주기만 하면 됩니다:

// Get the user
const { data: user } = useQuery({
queryKey: ['user', email],
queryFn: getUserByEmail,
})

const userId = user?.id

// Then get the user's projects
const {
status,
fetchStatus,
data: projects,
} = useQuery({
queryKey: ['projects', userId],
queryFn: getProjectsByUser,
// The query will not execute until the userId exists
enabled: !!userId,
})

projects 쿼리는 다음 상태로 시작합니다:

status: 'pending'
isPending: true
fetchStatus: 'idle'

user를 사용할 수 있게 되는 즉시 projects 쿼리는 enabled가 되고, 이후 다음 상태로 전환됩니다:

status: 'pending'
isPending: true
fetchStatus: 'fetching'

프로젝트를 가져오면 다음으로 이동합니다:

status: 'success'
isPending: false
fetchStatus: 'idle'

useQueries 종속 Query

동적 병렬 쿼리 - useQueries는 이전 쿼리에 의존할 수도 있으며, 다음과 같이 구현합니다:

// Get the users ids
const { data: userIds } = useQuery({
queryKey: ['users'],
queryFn: getUsersData,
select: (users) => users.map((user) => user.id),
})

// Then get the users messages
const usersMessages = useQueries({
queries: userIds
? userIds.map((id) => {
return {
queryKey: ['messages', id],
queryFn: () => getMessagesByUsers(id),
}
})
: [], // if userIds is undefined, an empty array will be returned
})

**useQueries쿼리 결과 배열을 반환한다는 점에 **유의하세요

성능에 관한 참고 사항

종속 쿼리는 정의상 요청 워터폴의 한 형태를 구성하며, 이는 성능을 저하시킵니다. 두 쿼리에 같은 시간이 걸린다고 가정하면, 병렬이 아닌 직렬로 수행할 경우 항상 두 배의 시간이 걸리며, 지연 시간이 긴 클라이언트에서 발생하면 특히 더 큰 문제가 됩니다. 가능하다면 두 쿼리를 병렬로 가져올 수 있도록 백엔드 API를 재구성하는 것이 항상 더 좋지만, 실제로 항상 가능하지는 않을 수 있습니다.

위 예시에서 getProjectsByUser할 수 있도록 먼저 getUserByEmail을 가져오는 대신 새로운 getProjectsByUserEmail 쿼리를 도입하면 워터폴이 평탄화됩니다.