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

React代码为何陷入无限循环?相同请求数据仍触发重复渲染

为什么这段React代码会陷入无限循环?

你写的这段代码之所以触发无限循环,核心问题出在对象引用的浅比较上:

原因分析

  1. 对象引用不同:每次fetch接口返回的data都是一个全新的JavaScript对象——哪怕它的内容和当前starWarsData完全一致,两者在内存中的引用地址也是不一样的。React检查useEffect依赖数组时,用的是严格相等(===)判断,新对象和旧对象的===结果为false,所以React会判定starWarsData这个依赖项发生了变化。
  2. 循环触发流程:
    • 组件首次渲染,useEffect执行,发起请求
    • 请求返回后调用setStarWarsData(data),更新状态,触发组件重新渲染
    • 重新渲染时,React发现starWarsData的引用变了,再次执行useEffect
    • 再次发起请求,得到新对象,更新状态,重新渲染……如此往复形成无限循环

解决方法

根据你的需求,有两种常见修复方式:

  1. 仅挂载时请求一次:如果只需要在组件第一次渲染时获取数据,直接把依赖数组设为空数组[],这样useEffect只会执行一次:
React.useEffect(function() {
    fetch("https://swapi.dev/api/people/1")
        .then(res => res.json())
        .then(data => setStarWarsData(data))
}, [])
  1. 内容变化才更新状态:如果确实需要基于starWarsData的变化触发请求,可以在更新状态前对比内容,只有当内容真的不同时才更新(注意:大对象用JSON.stringify对比性能较差,实际项目建议提取关键字段对比):
React.useEffect(function() {
    fetch("https://swapi.dev/api/people/1")
        .then(res => res.json())
        .then(data => {
            if (JSON.stringify(data) !== JSON.stringify(starWarsData)) {
                setStarWarsData(data)
            }
        })
}, [starWarsData])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 07:22:24