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

为何useQuery结合useEffect不会引发组件无限重渲染?

为什么这段React+Apollo代码不会无限重渲染?

我有如下代码片段:

const [state, setState] = useState(null);

const {data, loading, error} = useQuery(SOME_QUERY, {fetchPolicy: 'no-cache'});

useEffect(() => {
  setState(data)
}, [data]);

这段代码似乎仅渲染两次:一次是首次渲染,另一次是GraphQL请求完成后。我的疑问是:为何这不会导致组件无限重渲染?
我原本以为的流程是:组件渲染→useQuery发起请求→请求完成→useEffect更新state→触发再次渲染→useQuery再次发起请求,如此循环。
另外我也只看到一次网络请求,是否是useQuery在内部管理了这一切?


原因解析

  • useQuery不会重复发起无变化的请求:useQuery内部自带请求管理逻辑,同一个查询(查询语句、参数都不变)只会发起一次网络请求。哪怕组件重新渲染,只要查询的核心内容没改,它就不会再次触发请求——你设置的no-cache只是不把结果存入Apollo的全局缓存,但不影响它内部的重复请求拦截机制,所以你只会看到一次网络请求。

  • useEffect的依赖项稳定后不会重复执行:组件首次渲染时,data为undefined或null(处于loading状态);当请求完成,data更新为接口返回的实际数据,此时useEffect的依赖项data发生变化,触发setState(data),导致组件再次渲染。但这次重新渲染时,data已经是最终的稳定值,和上一次的data完全一致,useEffect的依赖项没有变化,所以不会再次执行,自然不会调用setState触发下一轮渲染,循环也就终止了。

  • 完整流程梳理:

    1. 组件首次渲染,useQuery发起请求,此时loading为true,data为空,useEffect因依赖项无变化不执行
    2. 请求完成,data更新,触发组件重新渲染,useEffect检测到data变化,执行setState更新组件state
    3. 组件因state更新再次渲染,此时useQuery返回的data已是最终值,和依赖项里的data完全相同,useEffect不执行,不再触发新的渲染或请求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 17:45:00