React中useEffect绑定count依赖时console.log打印顺序问题咨询
useEffect打印顺序成因说明
我们可以从React组件的生命周期和useEffect的执行规则两个维度拆解这个现象:
初始挂载阶段
- 组件首次渲染,
count的初始值为0 - useEffect的依赖项
count首次加载,没有上一轮的effect需要清理,直接执行effect回调函数:- 首先执行
console.log("b"),控制台输出b - 创建1秒定时器,绑定当前渲染闭包下的
tick函数 - 执行
console.log("c"),控制台输出c
- 首先执行
- 这个阶段就对应你看到的「初始运行先打印b和c」的现象
定时器触发后的更新阶段
- 1秒计时结束,执行
tick函数,调用setCount(count + 1)触发count更新,组件进入重渲染流程 - useEffect检测到依赖项
count的值发生变化,会严格按照「先清理上一轮effect,再执行本轮effect」的顺序执行:- 首先执行上一轮effect返回的清理函数:执行
console.log("a")输出a,同时清除上一轮创建的旧定时器 - 执行本次重渲染对应的effect回调函数:先打印b,再创建绑定了当前最新闭包的新1秒定时器,最后打印c
- 首先执行上一轮effect返回的清理函数:执行
- 后续每过1秒,定时器都会触发
count更新,重复上述的「清理旧effect→执行新effect」流程,所以每1秒都会依次打印a、b、c
额外补充
这段代码的写法存在频繁创建销毁定时器的冗余问题,如果要优化可以把tick里的更新改成函数式写法:setCount(prev => prev + 1),同时把useEffect的依赖项改为空数组,就可以只创建一次定时器实现同样的计数效果。
内容的提问来源于stack exchange,提问作者nodeDev
相关产品推荐
相关产品推荐

