依赖查询

useQuery 依赖查询

依赖查询(或串行查询)依赖于之前的查询完成后才能执行。要实现这一点,只需使用 enabled 选项来告知查询何时准备好运行即可。

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

const userId = computed(() => user.value?.id)
const enabled = computed(() => !!user.value?.id)

// Then get the user's projects
const { isIdle, data: projects } = useQuery({
  queryKey: ['projects', userId],
  queryFn: () => getProjectsByUser(userId.value),
  enabled, // The query will not execute until `enabled == true`
})
// Get the user
const { data: user } = useQuery({
  queryKey: ['user', email],
  queryFn: () => getUserByEmail(email.value),
})

const userId = computed(() => user.value?.id)
const enabled = computed(() => !!user.value?.id)

// Then get the user's projects
const { isIdle, data: projects } = useQuery({
  queryKey: ['projects', userId],
  queryFn: () => getProjectsByUser(userId.value),
  enabled, // The query will not execute until `enabled == true`
})

projects 查询开始时

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

一旦 user 可用,projects 查询就会被 enabled,然后过渡到

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

一旦我们有了项目,它将进入

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

useQueries 依赖查询

动态并行查询 - useQueries 也可以依赖于先前的查询,以下是如何实现这一点

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

const queries = computed(() => {
  return userIds.value.length
    ? userIds.value.map((id) => {
        return {
          queryKey: ['messages', id],
          queryFn: () => getMessagesByUsers(id),
        }
      })
    : []
})

// Then get the users messages
const usersMessages = useQueries({
  queries, // if userIds.value is undefined or has no items, 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),
})

const queries = computed(() => {
  return userIds.value.length
    ? userIds.value.map((id) => {
        return {
          queryKey: ['messages', id],
          queryFn: () => getMessagesByUsers(id),
        }
      })
    : []
})

// Then get the users messages
const usersMessages = useQueries({
  queries, // if userIds.value is undefined or has no items, an empty array will be returned
})

注意useQueries 返回一个查询结果数组

关于性能的注意事项

顾名思义,依赖查询构成了 请求瀑布流的一种形式,这会损害性能。如果我们假设这两个查询花费的时间相同,那么串行执行而不是并行执行总是需要两倍的时间,当客户端延迟很高时,这一点尤其有害。如果可能,最好重新组织后端 API,以便这两个查询可以并行获取,尽管这可能并不总是实际可行的。

在上面的示例中,而不是先获取 getUserByEmailgetProjectsByUser,引入一个新的 getProjectsByUserEmail 查询将能够扁平化瀑布流。