React中useEffect调用Axios发送post请求持续重复触发如何解决?
问题原因
- React 18 开发环境严格模式影响:React 18 开启
<StrictMode>后,开发环境下组件会经历「挂载 -> 卸载 -> 重新挂载」的流程,空依赖数组的useEffect会因此执行2次,属于开发环境的正常行为,生产环境不会触发。 - 组件重复挂载:如果请求次数远大于2次,优先排查当前组件是否被反复卸载/挂载,常见原因包括上层组件状态更新触发当前组件重渲染销毁、路由配置重复匹配到当前组件、列表渲染时生成了多个当前组件实例。
- Axios 自动重试逻辑触发:如果全局配置了Axios请求重试规则(比如使用
axios-retry插件、自定义请求拦截器重试逻辑),当/estimate接口返回非2xx状态码、跨域错误、超时等异常时,会触发自动重试,出现持续发送请求的现象。 - 未处理请求清理逻辑:如果请求响应速度慢,组件已经卸载但请求还在 pending,再次挂载时又会发起新的请求,极端情况下会出现多请求重叠的现象。
修复方案
- 首先确认是否是开发环境严格模式的正常行为:可以临时注释掉项目根目录的
<StrictMode>标签,观察请求是否还会重复发送,如果仅开发环境发2次,不需要额外处理,生产环境会自动恢复正常。 - 新增请求取消逻辑,在组件卸载时终止未完成的请求,示例代码如下:
useEffect(() => { // 实例化取消控制器 const controller = new AbortController(); axios.post("/estimate", { nana: "nana" }, { signal: controller.signal // 绑定取消信号 }).then(res => alert(res.data)) .catch(err => { // 忽略主动取消的请求报错 if (axios.isCancel(err)) return; // 其他错误正常处理 console.error(err); }); // 组件卸载时触发取消 return () => controller.abort(); }, []);
- 排查组件挂载逻辑:在当前组件的
useEffect中添加挂载日志,确认组件是否被多次实例化,依次检查上层组件的状态更新逻辑、路由配置、列表渲染规则,避免组件被重复生成。 - 检查Axios全局配置:确认是否开启了自动重试功能,调整重试阈值、重试条件,排除接口异常触发的重复请求。
- 兜底防重复发送:可以通过
useRef添加请求状态标记,避免同个组件实例多次发起请求,示例代码如下:
const hasRequestedRef = useRef(false); useEffect(() => { if (hasRequestedRef.current) return; hasRequestedRef.current = true; axios.post("/estimate", { nana: "nana" }).then(res => alert(res.data)); }, []);
内容的提问来源于stack exchange,提问作者junjune
相关产品推荐
相关产品推荐

