Dependent (or serial) queries depend on previous ones to finish before they can execute. To achieve this, it's as easy as using the enabled option to tell a query when it is ready to run:
// 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,
})
// 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,
})
The projects query will start in:
status: 'loading'
fetchStatus: 'idle'
status: 'loading'
fetchStatus: 'idle'
As soon as the user is available, the projects query will be enabled and will then transition to:
status: 'loading'
fetchStatus: 'fetching'
status: 'loading'
fetchStatus: 'fetching'
Once we have the projects, it will go to:
status: 'success'
fetchStatus: 'idle'
status: 'success'
fetchStatus: 'idle'
Dynamic parallel query - useQueries can depend on a previous query also, here's how to achieve this:
// 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 users is undefined, an empty array will be returned
})
// 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 users is undefined, an empty array will be returned
})
Note that useQueries return an array of query results