React中useEffect调用Axios请求Django接口无数据或死循环如何解决?
问题根因
- 空依赖数组下打印空数组不是请求未执行,是React的
setState为异步更新,调用setPrediction后当前渲染周期的predictions还是初始值,需要等下一次渲染才能拿到更新后的值,此时打印的是本次闭包缓存的旧数据,直接打印接口返回的response.data即可验证请求是否正常返回。 - 将
predictions加入依赖数组触发无限循环,是因为每次请求后更新predictions会触发useEffect重新执行,进而再次发起请求更新状态,形成无限调用链路。
最优实现方案(仅拉取一次数据,props.id变化时自动重新拉取)
直接将请求依赖的props.id加入useEffect依赖数组即可,无需放入predictions:
function IdentificationStep(props) { const [predictions, setPrediction] = useState([]); const [loadingState, setLoadingState] = useState(true); useEffect(() => { const getPredictions = async () => { try { const response = await axios.get('/snake-image/prediction/' + props.id); setPrediction(response.data); } catch (error) { console.error('请求出错:', error); } finally { setLoadingState(false); } }; getPredictions(); }, [props.id]); // 仅props.id变化时才重新发起请求,id不变则仅组件挂载时执行一次 }
如果确认props.id不会发生变化,依赖数组可以直接留空,和上述逻辑效果完全一致。原有的3秒超时修改loading状态的逻辑可以删除,改为请求结束后自动修改更合理。
自行实现方案说明
通过判断predictions长度规避无限循环的方案仅适用于接口返回数据长度固定大于等于3的场景,通用性较低,极端情况如果接口返回数据长度小于3还是会触发无限请求,建议优先使用依赖声明的标准方案。

内容的提问来源于stack exchange,提问作者Ilyes Negadi
相关产品推荐
相关产品推荐

