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

如何让React自定义Hook仅在Apollo加载完成且数据可用时执行?

问题解答

1. 你的自定义Hook实现存在问题

当前代码里的useEffect依赖数组只添加了id,但新增的loading参数未被纳入依赖,同时你用到的type也缺失在依赖数组中,这会导致两个问题:

  • 初始阶段loading为true,effect不执行,window.mydata不会被赋值
  • 当loading变为false时,如果id没有变化,这个effect不会重新触发,window.mydata依然无法被正确设置

正确的修改方式是把loading和type都加入依赖数组,调整后的代码如下:

useEffect(() => {
  if (!loading) {
    window.mydata = { id: `${id}`, type: `${type}` };
  }
}, [id, type, loading]); // 补充所有用到的依赖项

另外,如果你希望脚本也只在数据加载完成后再引入,需要注意useScript作为自定义Hook不能放在useEffect内部,可在Hook开头添加条件判断:

const useMyHook = ({ id, type, loading }: Props) => {
  // 仅在数据加载完成后加载脚本
  if (!loading) {
    useScript('https:domain/main.js');
    useScript('https://domain/main2.js');
  }

  useEffect(() => {
    if (!loading) {
      window.mydata = { id: `${id}`, type: `${type}` };
    }
  }, [id, type, loading]);
};

2. 片段查询先返回undefined的原因

这和Fragments无关,是Apollo Client useQuery的固有执行逻辑:

  • 组件首次渲染时,GraphQL请求还在处理中,Apollo还未拿到后端返回的数据,此时useQuery返回的data就是undefined,loading状态为true
  • 当请求成功完成、数据返回后,useQuery会更新状态,loading变为false,data被填充为查询结果,组件触发重新渲染,此时就能拿到有效数据

你之前在组件return里用!loading && foo控制的是UI渲染,但自定义Hook的执行不受return逻辑限制——组件挂载时Hook就会运行,不管return里的条件,所以即使UI不渲染,Hook里的初始逻辑依然会执行,导致window.mydata可能被提前设置为对应undefined的id值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 23:45:59