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

Apollo useLazyQuery的onCompleted回调触发两次问题求助

解决useLazyQuery的onCompleted回调触发两次问题

常见原因及对应解决方法

1. 组件重渲染导致回调重复绑定

如果组件因状态更新(比如setLoading)触发重渲染,useLazyQuery会重新初始化,导致回调重复绑定。可以用useCallback包裹onCompleted逻辑,保证函数引用稳定:

import { useCallback } from 'react';

// ...

const onCompleted = useCallback((data) => {
  console.log('called')
  if (data && data.details && data.details.color === 'blue') {
    releaseColor(mutationArgs)
  } else {
    // setError('Unit is not on Hold.')
  }
}, [mutationArgs]); // 按需添加依赖项

const [getComputers] = useLazyQuery(GET_COMPUTERS, {
  fetchPolicy: 'network-only',
  onCompleted,
})

const handleClick = () => {
  setLoading(true)
  getComputers()
}

2. 缓存更新或网络状态变化触发额外回调

即使设置了network-only,如果有其他操作(比如mutation)更新了相关缓存,或网络状态变化,可能触发查询重执行。可以关闭notifyOnNetworkStatusChange避免此类触发:

const [getComputers] = useLazyQuery(GET_COMPUTERS, {
  fetchPolicy: 'network-only',
  notifyOnNetworkStatusChange: false,
  onCompleted: (data) => {
    console.log('called')
    if (data && data.details && data.details.color === 'blue') {
      releaseColor(mutationArgs)
    } else {
      // setError('Unit is not on Hold.')
    }
  },
})

3. 检查是否重复调用getComputers

确认handleClick是否被意外触发两次(比如按钮绑定了多次事件、组件渲染时误调用)。可以用useRef记录调用次数,避免重复执行:

const callRef = useRef(0);

const handleClick = () => {
  if (callRef.current > 0) return;
  callRef.current += 1;
  setLoading(true)
  getComputers()
}

// 查询完成后重置计数
const onCompleted = useCallback((data) => {
  callRef.current = 0;
  if (data && data.details && data.details.color === 'blue') {
    releaseColor(mutationArgs)
  } else {
    // setError('Unit is not on Hold.')
  }
}, [mutationArgs]);

4. 改用useQuery控制查询时机(场景允许时)

如果不需要懒加载,用useQuery配合skip状态控制查询执行,可避免懒查询的重复回调问题:

const { refetch } = useQuery(GET_COMPUTERS, {
  skip: !shouldFetch, // 用状态控制是否执行查询
  fetchPolicy: 'network-only',
  onCompleted: (data) => {
    if (data && data.details && data.details.color === 'blue') {
      releaseColor(mutationArgs)
    } else {
      // setError('Unit is not on Hold.')
    }
  },
})

const handleClick = () => {
  setLoading(true)
  refetch()
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 09:20:07