React项目使用Axios调用API更新组件时如何避免无限递归循环
解决方案
你遇到的无限递归是因为componentDidUpdate生命周期在任何state更新后都会触发,没有前置校验的情况下,请求成功后调用setState会再次触发该生命周期,进入无限请求-更新的循环。
方案1:最小改动修复类组件逻辑
直接在现有componentDidUpdate中增加前置判断,仅当影响请求参数的location和timerangeId发生变化时才发起API请求:
componentDidUpdate(prevState) { // 仅当地点或时间范围变更时才发起请求 if (prevState.location !== this.state.location || prevState.timerangeId !== this.state.timerangeId) { axios.get(`/weather/api/location/${this.state.location}/${this.state.timerangeId}/temperature/`) .then((res) => { this.setState({data: res.data}); }) .catch((err) => console.log(err)); } }
方案2:更符合现代React开发习惯的重构(函数组件+Hooks)
如果愿意重构为函数组件,用useEffect钩子可以更直观的实现依赖变更触发请求的逻辑,代码可读性更强:
import { useState, useEffect } from 'react'; import axios from 'axios'; const WeatherVisualization = () => { const [location, setLocation] = useState('默认地点'); const [timerangeId, setTimerangeId] = useState('7d'); const [data, setData] = useState(null); // 仅当location或timerangeId变化时,触发请求 useEffect(() => { const fetchTemperatureData = async () => { try { const res = await axios.get(`/weather/api/location/${location}/${timerangeId}/temperature/`); setData(res.data); } catch (err) { console.log(err); } }; fetchTemperatureData(); }, [location, timerangeId]); // 依赖项明确指定触发请求的变量 // 其余渲染逻辑不变,传入对应的回调和数据给子组件即可 }
可选优化点
- 增加请求防抖逻辑,避免用户快速切换选项时发起大量无效请求
- 新增loading状态,请求过程中给用户明确的加载反馈
- 增加请求取消逻辑,组件卸载或者依赖变更时取消上一次未完成的请求,避免内存泄漏
内容的提问来源于stack exchange,提问作者kiril
相关产品推荐
相关产品推荐

