React函数组件生命周期:代码执行时机与顺序问询
React函数组件生命周期与代码执行时机解析
先看你的示例代码:
const Countdown = () => { let x = 0; const [countDown, setCountDown] = useState(10) x = x + 1 if(x > 100) { x = 0 } useEffect(() => { const interval = setInterval(() => { setCountDown(countDown - 1); console.log(x) }, 1000); }, [countDown]); };
问题解答
countDown状态与x变量的声明时机
两者的声明都在useEffect之前。React函数组件每次渲染时,会从头到尾执行整个组件函数体的同步代码,let x = 0和useState的调用都在useEffect语句之前,所以它们的声明和初始化会先于useEffect的回调执行(注意:useEffect的回调是在渲染完成后才执行的,不是组件函数执行时立刻运行)。if代码块是否属于useEffect的执行范围
不属于。这个if代码块是直接写在组件函数体里的同步代码,会在组件每次渲染时执行,和useEffect的回调完全是两个独立的执行阶段——if块在组件渲染过程中执行,而useEffect回调是在渲染完成、DOM更新后才触发的。
页面加载时的完整执行顺序
当页面首次加载、组件挂载时,执行流程是这样的:
- 起始点:React调用
Countdown组件函数,开始执行组件的同步代码。 - 第一步:声明并初始化变量
x = 0。 - 第二步:调用
useState(10),初始化countDown状态为10,同时拿到更新状态的setCountDown方法。 - 第三步:执行
x = x + 1,此时x的值变为1。 - 第四步:执行
if(x > 100)判断,因为x=1不满足条件,跳过内部赋值逻辑。 - 第五步:React完成组件的渲染工作,把生成的DOM挂载到页面上。
- 第六步:触发
useEffect的回调(因为是首次挂载,依赖项countDown存在),在回调里创建定时器,定时器每隔1秒执行一次内部逻辑。
另外要注意:每次调用setCountDown更新countDown状态时,组件会重新渲染,整个Countdown函数会再次从头执行一遍——这时候会重新声明一个新的x变量,重新执行所有同步代码,之后React对比DOM差异更新页面,再根据countDown的新值判断是否重新执行useEffect的回调。
内容的提问来源于stack exchange,提问作者bami
相关产品推荐
相关产品推荐

