依赖型查询
useQuery 依赖型查询
依赖型(或串行)查询需等待前一个查询完成之后才能执行。要实现这一点,只需使用 enabled 选项来告知查询它何时已准备好运行:
TypeScript
1// Get the user2const userQuery = useQuery(() => ({3 queryKey: ['user', email],4 queryFn: getUserByEmail,5}))6 7const userId = () => userQuery.data?.id8 9// Then get the user's projects10const projectsQuery = useQuery(() => ({11 queryKey: ['projects', userId()],12 queryFn: getProjectsByUser,13 // The query will not execute until the userId exists14 enabled: !!userId(),15}))projects 查询将起始于:
TypeScript
1status: 'pending'2isPending: true3fetchStatus: 'idle'一旦 user 可用,projects 查询便会变为 enabled 状态,并随即过渡到:
TypeScript
1status: 'pending'2isPending: true3fetchStatus: 'fetching'获取项目后,它将进入:
TypeScript
1status: 'success'2isPending: false3fetchStatus: 'idle'useQueries 依赖型查询
动态并行查询——useQueries 同样可依赖于前一个查询,实现方式如下:
TypeScript
1// Get the users ids2const usersQuery = useQuery(() => ({3 queryKey: ['users'],4 queryFn: getUsersData,5 select: (users) => users.map((user) => user.id),6}))7 8// Then get the users messages9const usersMessages = useQueries(() => ({10 queries: usersQuery.data11 ? usersQuery.data.map((id) => {12 return {13 queryKey: ['messages', id],14 queryFn: () => getMessagesByUsers(id),15 }16 })17 : [], // if usersQuery.data is undefined, an empty array will be returned18}))注意:useQueries 返回的是一个查询结果数组。
关于性能的一点说明
按定义,依赖型查询构成了一种 请求瀑布,这会损害性能。假设两个查询耗时相同,串行执行它们所需时间总是并行执行的两倍;当这种情况发生在高延迟客户端上时,性能损耗尤为明显。如果可行,最好重构后端 API,使两个查询能够并行拉取;不过这在实践中并不总是切实可行。
在上述示例中,与其先拉取 getUserByEmail 再据此拉取 getProjectsByUser,不如引入一个新的 getProjectsByUserEmail 查询,从而压平该请求瀑布。