React useEffect中Axios异步GET请求重复执行两次问题排查
Axios GET请求重复触发两次问题排查
问题基础信息
- 异常表现:Axios GET请求在调用时固定重复执行2次
- 已尝试操作:移除
React.StrictMode标签后问题无改善,初始怀疑异常由webpack dev server导致 - 关联现象:空依赖useEffect内写入的
console.log("hi")同样重复输出2次,浏览器网络面板可观测到2条完全一致的请求记录
关联代码
自定义GET请求封装
export default async function useSendResquest(url, handler) { var Response; Response = await axios.get(url).then((response) => { return response.data; }); return handler(Response); }
useEffect调用逻辑
useEffect(() => { useSendResquest( "http://localhost:8080/api/control?name=rgbLed&status", (Response) => { setLightState(Response); } ); console.log("hi"); }, []);
问题现象截图
- 网络面板请求记录:

- 控制台打印记录("hi"日志重复输出两次):

排查&修复思路
- 优先验证React 18+ 开发环境严格模式影响
不要只检查根入口文件是否删除React.StrictMode包裹,部分上层框架(Next.js、Umi、新版Create React App等)会内置强制开启严格模式,手动删除根节点包裹不生效。React 18严格模式在开发环境下会主动重复执行一次组件挂载、effect执行流程,用于提前暴露未做清理的副作用问题,该机制和webpack dev server无直接关联。快速验证方法:执行
npm run build打生产环境包,用静态服务启动生产构建产物后访问页面,如果请求仅发送1次,即可确定是开发环境严格模式的重复执行机制导致,不属于业务代码bug。 - 检查组件重复挂载问题
排查父组件逻辑,确认是否存在条件渲染、路由重复跳转、组件绑定的key值动态变化等情况,空依赖的useEffect会在组件每次挂载时执行,组件如果被连续挂载2次,就会触发2次请求和2次控制台日志打印。 - 修正函数命名问题
你的请求函数以use开头,会被React识别为自定义Hook,但该函数本质是普通异步请求工具函数,不符合Hook的调用规则,可能触发React运行时的异常检测逻辑。将函数名改为不带use前缀的普通命名即可,同时建议不要混用await和.then写法,简化代码逻辑:// 去掉use前缀,简化异步写法 export default async function sendRequest(url, handler) { const { data } = await axios.get(url) return handler(data) } - 排查热更新配置异常
部分webpack dev server的热更新(React Refresh)配置存在问题时,会在页面初始化阶段重复执行一次组件挂载逻辑,可临时关闭热更新配置测试请求是否还会重复发送。 - 补充effect清理逻辑
给useEffect增加返回的清理函数,搭配AbortController中断组件卸载时未完成的请求,避免重复触发的请求造成不必要的状态更新:useEffect(() => { const abortController = new AbortController() sendRequest( "http://localhost:8080/api/control?name=rgbLed&status", (data) => { setLightState(data); } ); console.log("hi"); return () => abortController.abort() }, []);
内容的提问来源于stack exchange,提问作者Barry Allen
相关产品推荐
相关产品推荐

