React中useEffect触发两次请求/日志,如何改为仅执行一次?
解决useEffect执行两次API请求的问题
问题原因
React 18及以上版本的开发环境中,StrictMode会强制组件挂载两次(模拟卸载后重新挂载),以此检测内存泄漏等潜在问题。这就导致空依赖的useEffect会执行两次,API请求也会触发两次,console.log自然输出两次。生产环境下StrictMode不会生效,不会出现这个问题。
解决方案
方案1:在开发环境中跳过重复执行(推荐)
使用useRef标记请求是否已经执行过,第一次执行后更新标记,后续不再触发请求:
import { useEffect, useRef } from 'react'; import axios from 'axios'; // 组件内部 const hasFetched = useRef(false); useEffect(() => { const fetchData = async () => { try { // 简化写法,避免await和then混用 const res = await axios.get("someurl.com/test", {}); console.log("data: ", res.data); } catch (err) { console.log("Error: ", err); } }; // 仅在未请求过时执行 if (!hasFetched.current) { fetchData(); hasFetched.current = true; } }, []);
方案2:关闭StrictMode(仅临时测试用,不推荐)
找到项目入口文件(如index.js或main.jsx),移除<StrictMode>标签的包裹:
// 修改前 ReactDOM.createRoot(document.getElementById('root')).render( <StrictMode> <App /> </StrictMode> ); // 修改后 ReactDOM.createRoot(document.getElementById('root')).render( <App /> );
注意:关闭StrictMode会失去React提供的bug检测能力,不建议在开发中长期使用。
额外优化点
你的代码中同时使用了await和.then(),属于冗余写法,直接用await获取响应结果即可,让代码更简洁易读。
内容的提问来源于stack exchange,提问作者Muhammed Didin
相关产品推荐
相关产品推荐

