依赖查询(或串行查询)必须等待之前的查询完成后才能执行。为了实现这一点,只需使用 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,
})
// 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'
status: 'pending'
isPending: true
fetchStatus: 'idle'
一旦 user 可用,projects 查询就会被 enabled,然后过渡到
status: 'pending'
isPending: true
fetchStatus: 'fetching'
status: 'pending'
isPending: true
fetchStatus: 'fetching'
一旦我们有了项目,它将进入
status: 'success'
isPending: false
fetchStatus: 'idle'
status: 'success'
isPending: false
fetchStatus: 'idle'
动态并行查询 - 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
})
// 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,以便两个查询可以并行获取,尽管这可能并非总是切实可行。
在上面的示例中,而不是先获取 getUserByEmail 以便能够 getProjectsByUser,引入一个新的 getProjectsByUserEmail 查询将能够扁平化瀑布。