React未触发点击渲染3次且最后一次无useEffect执行的问题咨询
问题原因拆解
你的代码的行为完全符合React的运行逻辑,我们一步步拆解执行流程就可以理清:
- useEffect没有配置依赖数组
你写的useEffect没有传入第二个参数的依赖数组,这会导致它在每一次组件渲染完成后都会执行,这是后续多次重渲染的根源。 - 前两次渲染的执行流程
- 第一次挂载渲染:
初始化状态trackIndex=1、trackProgress=0,控制台打印render。渲染完成后执行useEffect,符合trackIndex<5的条件,调用setTrackProgress(1)触发状态更新,进入重渲染流程。 - 第二次渲染:
trackProgress更新为1,控制台打印render。渲染完成后再次执行useEffect,此时trackIndex依然是1,满足条件再次调用setTrackProgress(1),这次传入的新值和当前trackProgress的值完全一致。
- 第一次挂载渲染:
- 第三次渲染的触发原因
当你调用setState传入的新值和当前状态值通过Object.is判断完全相等时,React会做一次优化校验:它会先执行一次组件渲染,确认所有状态和渲染输出是否真的没有变化,这就是你看到的第三次render打印的来源。 - 第三次渲染后没有执行useEffect的原因
这次渲染完成后,React校验确认所有状态都没有发生变更,因此会跳过后续的副作用(useEffect)执行、DOM更新等流程,所以不会有useEffect的输出。
修复建议
如果要避免这种无意义的重复执行,只需要给useEffect添加对应的依赖数组即可,比如你只需要在trackIndex变化的时候更新trackProgress,就修改为:
useEffect(() => { console.log("effect; trackIndex=",trackIndex) console.log("effect; trackProgress=",trackProgress) if(trackIndex<5){ console.log("set trackProgress") setTrackProgress(trackIndex) } }, [trackIndex]); // 仅在trackIndex变化时执行
添加依赖后,初始只会渲染2次,不会出现第三次无意义的渲染。
内容的提问来源于stack exchange,提问作者Allen
相关产品推荐
相关产品推荐

