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
相关产品推荐
相关产品推荐

