React 开启 Strict Mode 后 useEffect 被执行了两次,正常吗? 极客钰曦 提问于 2026-02-24 22:45:17 阅读 49 框架 我在开发 React 应用时开启了 Strict Mode,结果发现组件里的 useEffect 在开发环境下执行了两次,导致接口被请求了两遍,这正常吗?我是不是哪里写错了? 这是我的代码: useEffect(() => { console.log('Fetching data...'); fetchData(); }, []); ReactRedux性能优化 我来解答 赞 11 收藏 分享 生成中... 手机扫码查看 复制链接 生成海报 反馈 发表解答 您需要先 登录/注册 才能发表解答 2 条解答 极客赛赛 Lv1 这很正常,Strict Mode在开发环境会故意重复调用useEffect来帮你发现潜在问题。加个ref标记解决: const mountedRef = useRef(false); useEffect(() => { if (!mountedRef.current) { mountedRef.current = true; console.log('Fetching data...'); fetchData(); } }, []); 或者用axios的话可以直接cancel掉重复请求 回复 点赞 2026-03-07 01:04 ❤志诚 Lv1 这事儿我太熟了,当年我也被这个坑过好几次。Strict Mode 在开发环境里故意把 useEffect 的回调执行两次,是它故意设计的,不是你写错了。目的就一个:帮你提前发现那些「副作用没做好清理」或者「依赖没写全」的隐性 Bug。 比如你这个例子里,如果 fetchData 是个网络请求,那它确实会发两次,但注意——生产环境不会这样,只有开发环境会。所以你要是上线后发现正常了,别慌,就是这个机制在起作用。 怎么验证?你可以打包后跑 npm run build && serve -s build 看看,就一次了。 不过既然它触发了两次,说明你这副作用得认真检查下: - 有没有在 fetchData 里没做防重处理?比如加个 loading 标志,或者 abort 上一次请求 - 有没有依赖项漏写?比如 fetchData 本身是不是用 useCallback 包的?要是没包,每次 render 都是新函数,那就算你写了空数组也会重执行 - 清理函数写没写?比如请求取消、订阅取消这些,Strict Mode 会调用两次,第一次执行完会立刻再执行一次,中间夹着个清理函数 要是你就是想临时屏蔽这个双执行(比如调试阶段怕日志刷屏),可以在开发时用 process.env.NODE_ENV === 'development' 包一层,但不推荐长期这么干,毕竟漏掉的问题迟早要还。 我以前在主题里加过一个全局的 console.warn 拦截,专门打印 useEffect 重复执行的 stack trace,后来发现真查出好几次没清理的订阅,血亏。所以这事儿别当成 bug 解决,当成个提醒机制就好。 回复 点赞 6 2026-02-24 23:01 加载更多 相关推荐 2 回答 34 浏览 React Strict Mode 下 useEffect 为什么会执行两次? 我在开发时开启了 React 的 Strict Mode,结果发现 useEffect 里的逻辑执行了两次,明明只渲染了一次组件。这是正常现象吗?会不会影响生产环境? 我试过把依赖数组清空,也试过移除... 慕容梓晨 框架 2026-03-02 17:50:20 1 回答 38 浏览 React Strict Mode 下 useEffect 为什么会执行两次? 我最近在开发一个 React 项目,启用了 Strict Mode 后发现 useEffect 里的逻辑执行了两次,比如发请求、打日志都重复了。明明只渲染了一次组件,为啥会这样?是不是我写法有问题? ... Air-晨晰 框架 2026-03-12 19:21:21 1 回答 77 浏览 React Strict Mode为什么导致useEffect两次执行?代码没问题却报错 我在React组件里用Strict Mode包裹App时,发现useEffect里的API请求执行了两次,控制台还报错说useState未定义。但移除Strict Mode后就正常了,这是为什么? 比... ♫慧慧 框架 2026-02-19 10:09:50 2 回答 42 浏览 React 开启 Strict Mode 后 useEffect 为啥执行了两次? 我在开发 React 应用时,发现只要在根组件包了 StrictMode,里面的 useEffect 就会执行两次,明明只写了一次逻辑。这是 bug 吗?还是我哪里理解错了? 比如下面这段代码,在控制... 司卿 框架 2026-02-26 16:40:21 2 回答 55 浏览 React中setTimeout和useEffect的执行顺序为什么不符合预期? 我在用React写一个计数器组件,点击按钮后先调用setTimeout再更新状态,但发现useEffect里的console.log总是先于setTimeout里的输出。明明setTimeout在代码... 技术巧梅 前端 2026-02-17 22:26:26 1 回答 41 浏览 Jest 测试中如何正确模拟 React 组件的异步 useEffect? 我在用 Jest + React Testing Library 测试一个组件,它在 useEffect 里发起了异步请求。测试总是报“无法在未挂载的组件上执行 setState”,我试过用 awai... 令狐倩利 框架 2026-03-05 14:04:22 2 回答 77 浏览 Figma Dev Mode导出的组件样式在React中不生效怎么办? 我用Figma Dev Mode导出的按钮组件CSS,在React项目里直接复制粘贴后样式完全没效果。按钮显示成默认的方形,颜色也没变化。之前按照文档配置了正确的类名,但检查元素发现CSS变量好像没被... Mr-景叶 工具 2026-02-16 04:41:37 2 回答 45 浏览 React中使用strict-dynamic后动态内联样式还是被CSP拦截怎么办? 最近给项目加CSP防护时遇到怪事,按照文档在nonce策略里加了'strict-dynamic',但React组件里的动态内联样式还是被拦截。明明设置了nonce和函数生成样式啊... 代码大概是这样... Good“秀玲 安全 2026-01-26 23:09:29 2 回答 23 浏览 useEffect 为什么在组件首次渲染时就执行了? 我刚学 React,看到 useEffect 默认会在组件挂载后执行一次,但我不太理解为什么它不等依赖变化才运行。比如我在 Vue 里用 watch 是不会一进来就触发的,但在 React 里写了个空... 码农翌耀 框架 2026-03-02 22:19:21 2 回答 32 浏览 React中如何正确监听全局快捷键而不触发多次? 我在用React做编辑器功能,想用Ctrl+S保存,但每次按键都会触发好几次保存请求,试过在useEffect里加事件监听,也用了removeEventListener清理,但还是不行。 是不是我的写... 红瑞 Dev 交互 2026-03-23 19:31:18
或者用axios的话可以直接cancel掉重复请求
比如你这个例子里,如果
fetchData是个网络请求,那它确实会发两次,但注意——生产环境不会这样,只有开发环境会。所以你要是上线后发现正常了,别慌,就是这个机制在起作用。怎么验证?你可以打包后跑
npm run build && serve -s build看看,就一次了。不过既然它触发了两次,说明你这副作用得认真检查下:
- 有没有在
fetchData里没做防重处理?比如加个 loading 标志,或者 abort 上一次请求- 有没有依赖项漏写?比如
fetchData本身是不是用useCallback包的?要是没包,每次 render 都是新函数,那就算你写了空数组也会重执行- 清理函数写没写?比如请求取消、订阅取消这些,Strict Mode 会调用两次,第一次执行完会立刻再执行一次,中间夹着个清理函数
要是你就是想临时屏蔽这个双执行(比如调试阶段怕日志刷屏),可以在开发时用
process.env.NODE_ENV === 'development'包一层,但不推荐长期这么干,毕竟漏掉的问题迟早要还。我以前在主题里加过一个全局的
console.warn拦截,专门打印 useEffect 重复执行的 stack trace,后来发现真查出好几次没清理的订阅,血亏。所以这事儿别当成 bug 解决,当成个提醒机制就好。