React useEffect依赖allGroups时无限发起fetch请求的解决方案
问题根因
你当前的代码写法触发了 useEffect 死循环,完整执行链路如下:
- 组件首次挂载,触发 useEffect 执行
- useEffect 内发起接口请求,拿到返回值后调用
setAllGroups(arr)更新状态 - 状态更新触发组件重渲染,React 对 useEffect 依赖项做浅比较:你每次 setState 传入的都是循环中新创建的数组
arr,即便数组内的元素和旧的allGroups完全相同,新数组的内存引用地址和旧状态也不一致,React 会判定依赖项发生变化 - 依赖项变更会再次触发 useEffect 执行,重复走「发请求→更新状态→重渲染→判定依赖变化」的流程,最终出现无限执行的问题
修复方案
根据你的业务场景(初始化加载下拉选项),这个接口请求只需要在组件首次挂载时拉取一次即可,直接把 useEffect 的依赖数组改为空数组,就能让逻辑只在组件挂载阶段执行一次,不会重复触发:
const [allGroups, setAllGroups] = useState([]) useEffect(() => { console.log("useEffect") // 获取全部分组 fetch("http://localhost:8080/group/getAll") .then(response => response.json()) .then(data => { // 原循环逻辑可以简化为map写法 const groupNames = data.map(item => item.groupName) setAllGroups(groupNames) }) }, []) // 空依赖数组 = 仅组件首次挂载时执行
其他场景说明
如果你后续确实需要在某个条件变化时重新拉取分组数据(比如切换上级组织后刷新分组列表),只需要把触发刷新的源变量(比如组织ID)放进依赖数组即可,不要把 useEffect 内会更新的状态本身放进依赖数组,否则很容易再次触发死循环。
额外优化提示:你当前下拉列表渲染用遍历索引
i作为 key,如果后续分组列表存在排序、新增、删除操作,可能引发渲染错位问题,建议用分组的唯一业务标识(比如后端返回的 groupId)作为 key 值。
内容的提问来源于stack exchange,提问作者Nathan
相关产品推荐
相关产品推荐

