此问题已在下面给出相关帖子和答案的链接后进行了编辑。根据我的理解,在初始渲染期间的严格模式下,React 会渲染一个组件两次:
在严格模式下,React 会调用你的组件函数两次,以帮助你发现意外的杂质。这只是开发行为,不会影响生产。 每个 ref 对象都会被创建两次,但其中一个版本将被丢弃。
接下来将一个渲染提交给浏览器 DOM。提交到正在安装的浏览器 DOM 后,Effect 会运行一次。通过新的 React 18 功能,组件被卸载(从浏览器 DOM 中删除)。运行效果中提到的任何清理。卸载后,组件会再次从正在重新挂载的虚拟 DOM 提交到浏览器 DOM。这个重新安装过程不是由渲染引起的,甚至不是由渲染触发的。它只是从虚拟 DOM 到浏览器 DOM 的协调。由于组件再次提交到浏览器 DOM,因此 useEffect 再次运行。
对于初始渲染后的后续重新渲染,组件会渲染两次,但仅提交(挂载)一次。因此 useEffect 运行一次。
我的理解有什么遗漏或者有漏洞吗?
初始渲染:
在严格模式下,React 会调用你的组件函数两次,以帮助你发现意外的杂质。这只是开发行为,不会影响生产。 每个 ref 对象都会被创建两次,但其中一个版本将被丢弃。
这就是为什么
ref.current
在 UI 中是 1
且 ref2.current
是 0
。
传入的效果函数
useEffect()
会在调用组件函数后执行。
组件安装时效果运行两次
当严格模式开启时,在开发过程中,React 会在实际设置之前额外运行一次设置和清理操作。
因此
ref2.current += 1
将在效果函数中执行两次。该值变为 2
,但此时 UI 中显示的 ref2.current
是 0
,因为我们没有更新状态并触发组件的下一次渲染。
当点击按钮时,更新标志状态,触发组件的下一次渲染。
ref2.current
将在 UI 上显示 2
。
严格模式下:
你的组件将重新渲染额外的时间来查找不纯渲染引起的错误。
ref.current += 1
会执行两次,所以UI中的ref.current: 3
useEffect()
中的效果函数会在组件更新后执行一次(参见我的Effect在每次重新渲染后运行),因此效果函数中的ref2.current
变为3
。
再次点击按钮,触发下一次渲染。
ref.current
将显示5
,ref2.current
将显示3
。
然后,
7
和4
,9
和5
,11
和6
,继续这样下去
查看此示例的控制台日志