You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

咨询修复Apollo useQuery钩子渲染错误:依赖查询结果的调用问题

修复useQuery依赖前置数据导致的渲染错误

问题场景

当前使用3个useQuery钩子,其中OSData查询的变量NUMBER依赖于GET_Ram和GET_Hardware查询生成的UniqueList。直接调用OSData查询会出现变量未定义问题,延后调用又触发Hook渲染错误,需解决这一矛盾。

原代码示例:

const {
  data: OSData,
  error: OSError,
  loading: OSLoading,
} = useQuery(OSData, { // 注:此处第一个参数应为查询键(如'GET_OS')或查询函数,原代码可能存在笔误
  variables: {
    NUMBER: UniqueList,
  },
})

const {
  data: RamData,
  error: RamERROR,
  loading: RamLOADING,
} = useQuery(GET_Ram)

const {
  data: Hardware,
  error: HardwareERROR,
  loading: HardwareLOADING,
} = useQuery(GET_Hardware)

解决方案

1. 使用enabled参数控制查询触发时机

React Query的useQuery内置了enabled选项,仅当该值为true时才会执行查询。我们可以通过判断RamData、Hardware是否就绪,以及UniqueList是否已生成,来决定是否启用OSData查询:

// 先获取Ram和Hardware数据
const {
  data: RamData,
  error: RamERROR,
  loading: RamLOADING,
} = useQuery(GET_Ram)

const {
  data: Hardware,
  error: HardwareERROR,
  loading: HardwareLOADING,
} = useQuery(GET_Hardware)

// 生成UniqueList(假设这里是基于RamData和Hardware的处理逻辑)
const UniqueList = useMemo(() => {
  if (!RamData || !Hardware) return []
  // 此处替换为实际生成UniqueList的逻辑
  return [...new Set([...RamData.items, ...Hardware.items])]
}, [RamData, Hardware])

// 仅当UniqueList有效时,才执行OSData查询
const {
  data: OSData,
  error: OSError,
  loading: OSLoading,
} = useQuery('GET_OS', { // 修正查询键为合理值
  variables: {
    NUMBER: UniqueList,
  },
  enabled: UniqueList.length > 0 && !RamLOADING && !HardwareLOADING
})

2. 用useQueries批量管理前置查询

如果GET_Ram和GET_Hardware是并行执行的,可以用useQueries批量获取这两个数据,统一判断就绪状态:

const [RamResult, HardwareResult] = useQueries([
  { queryKey: 'GET_Ram', queryFn: GET_Ram },
  { queryKey: 'GET_Hardware', queryFn: GET_Hardware }
])

const { data: RamData, loading: RamLOADING } = RamResult
const { data: Hardware, loading: HardwareLOADING } = HardwareResult

const UniqueList = useMemo(() => {
  if (!RamData || !Hardware) return []
  // 实际生成逻辑
  return [...new Set([...RamData.items, ...Hardware.items])]
}, [RamData, Hardware])

const {
  data: OSData,
  error: OSError,
  loading: OSLoading,
} = useQuery('GET_OS', {
  variables: { NUMBER: UniqueList },
  enabled: !RamLOADING && !HardwareLOADING && UniqueList.length > 0
})

3. 手动触发查询(useQueryClient)

如果需要更灵活的控制逻辑,可以使用useQueryClient的fetchQuery方法,在useEffect中监听前置数据的变化,手动触发OSData查询:

const queryClient = useQueryClient()

const {
  data: RamData,
  loading: RamLOADING,
} = useQuery(GET_Ram)

const {
  data: Hardware,
  loading: HardwareLOADING,
} = useQuery(GET_Hardware)

const UniqueList = useMemo(() => {
  if (!RamData || !Hardware) return []
  // 实际生成逻辑
  return [...new Set([...RamData.items, ...Hardware.items])]
}, [RamData, Hardware])

// 存储OSData的状态
const [OSData, setOSData] = useState(null)
const [OSLoading, setOSLoading] = useState(false)
const [OSError, setOSError] = useState(null)

useEffect(() => {
  // 前置数据未就绪时不执行
  if (RamLOADING || HardwareLOADING || UniqueList.length === 0) return

  const fetchOSData = async () => {
    setOSLoading(true)
    try {
      const data = await queryClient.fetchQuery('GET_OS', {
        variables: { NUMBER: UniqueList }
      })
      setOSData(data)
    } catch (err) {
      setOSError(err)
    } finally {
      setOSLoading(false)
    }
  }

  fetchOSData()
}, [RamLOADING, HardwareLOADING, UniqueList, queryClient])

关键注意点

  • 确保UniqueList的生成逻辑使用useMemo缓存,避免不必要的重计算和查询触发。
  • 原代码中useQuery(OSData, ...)的第一个参数应为查询键(字符串/数组)或查询函数,需修正为正确值,否则会导致查询逻辑异常。

内容的提问来源于stack exchange,提问作者user18175092

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 18:24:04