React组件首次渲染时如何阻止useEffect内代码执行?
问题原因分析
你用全局变量isInitial的方式失效,核心原因是React开发环境的严格模式会触发组件双重渲染:
- 第一次渲染时,
useEffect执行,把全局的isInitial设为false; - 第二次渲染时,全局变量已经是
false,所以useEffect里的判断不生效,直接执行setMessage('Executed'),导致最终显示Executed。 - 另外,全局变量还会带来额外问题:如果组件后续被多次挂载(比如路由切换),
isInitial会保持之前的false状态,导致后续挂载的组件也会跳过首次useEffect,不符合需求。
正确解决方案:使用useRef保存初始化状态
用useRef替代全局变量,因为useRef的.current属性在组件整个生命周期内保持唯一引用,且初始赋值仅在组件首次挂载时生效:
import { useEffect, useState, useRef } from 'react'; function App() { const [message, setMessage] = useState('First'); const isInitial = useRef(true); useEffect(() => { if (isInitial.current) { isInitial.current = false; return; } setMessage('Executed'); }, []); return <p>{message}</p>; } export default App;
为什么useRef能解决问题?
useRef创建的对象在组件每次渲染时都会返回同一个实例,初始值true只会设置一次;- 即使在严格模式下双重渲染,第一次
useEffect把isInitial.current设为false后,第二次useEffect执行时会直接return,不会触发setMessage,最终页面会显示预期的First; - 组件每次重新挂载时,
useRef都会重新初始化true,不会影响其他挂载实例。
内容的提问来源于stack exchange,提问作者Chathura Kudahetti
相关产品推荐
相关产品推荐

