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

React中useEffect依赖state未变更却触发无限循环问题咨询

无限循环的原因

你当前的代码死循环本质是useEffect依赖逻辑和状态更新逻辑形成了闭环:

  • React规定useEffect会在每次依赖数组内的变量发生值/引用变更时,重新执行内部回调函数
  • 你在回调内调用setSuperheroes(response)更新superheroes状态,而superheroes本身就是你放在依赖数组里的监听对象
  • 即便接口返回的列表内容和之前完全一致,response.json()返回的永远是新的数组引用,React会判定superheroes状态发生了变更,进而再次触发useEffect执行,形成「调接口→更新状态→触发useEffect→再调接口」的无限循环。

正确实现方案

你的核心逻辑错误是:把要更新的目标状态当成了触发拉取的依赖条件。正常情况下,触发列表重新拉取的应该是会影响接口返回结果的查询参数,比如筛选关键词、页码、排序规则,而非你要赋值的列表本身。

示例实现(依赖查询参数触发拉取):

const [superheroes, setSuperheroes] = useState([]);
// 示例:会影响列表返回结果的查询参数
const [keyword, setKeyword] = useState('');
const [pageNum, setPageNum] = useState(1);

useEffect(() => {
    apiCall(`/superheroes?keyword=${keyword}&page=${pageNum}`, { method: 'GET'})
    .then(response => response.json())
    .then(data => {
        setSuperheroes(data);
    }).catch(x=> console.log("ERROR: " + x))
}, [keyword, pageNum]) // 依赖改为查询参数,而非superheroes

如果你的场景没有额外查询参数,只是需要手动触发刷新,可以单独加一个刷新触发器:

const [superheroes, setSuperheroes] = useState([]);
const [refreshFlag, setRefreshFlag] = useState(0);

useEffect(() => {
    apiCall('/superheroes', { method: 'GET'})
    .then(response => response.json())
    .then(data => {
        setSuperheroes(data);
    }).catch(x=> console.log("ERROR: " + x))
}, [refreshFlag])

// 需要刷新列表时调用该方法即可
const refreshList = () => {
    setRefreshFlag(prev => prev + 1);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 05:18:00