使用 React 的前端开发人员一直使用useEffect
挂钩来呈现副作用。
但是你知道有一个类似但略有不同的钩子叫做useLayoutEffect
吗?我没有,直到我偶然发现了这个钩子的一个实例,它在我参与的一个代码库中使用。
这是一个深入了解两者之间差异的博客,并了解何时以及何时不使用它们。
区别
简而言之,区别在于精度。
-
useEffect
运行,但无法保证确切发生的时间。它是在像素的布局和绘制之后运行的异步操作。 -
相比之下,
useLayoutEffect
保证立即运行。这是一个同步操作,发生在所有 DOM 突变之后,浏览器可以绘制像素之前。如果你熟悉 React 类组件中的componentDidMount
生命周期,这基本上是等效的行为。
useLayoutEffect 似乎更胜一筹。我们应该将它用于一切吗?
但是为什么我们不想一直使用 useLayoutEffect 呢?
没那么快。与所有事物一样,精确是有代价的。
React 优化useEffect
以提高性能。在使用 React 时,我们需要对副作用进行大量编程,而useEffect
内置的性能增强将大大增加。
React 团队明确鼓励用户尽可能使用useEffect
以避免阻塞视觉更新。
用 React 官方文档在“效果时间”下的话来说:
… 在延迟事件期间,传递给 useEffect 的函数在布局和绘制之后触发。这使它适用于许多常见的副作用,例如设置订阅和事件处理程序,因为大多数类型的工作不应该阻止浏览器更新屏幕。
旁注:React 团队最近在 React 18 中升级useEffect
以使其与用户点击等常见事件同步,更不用说你使用useLayoutEffect
钩子的理由了。
那么我们什么时候应该使用useLayoutEffect呢?
这通常归结为一个主要原因:
当您需要测量 DOM 并提供计算的即时视觉反馈时(因此名称中的“布局”)。
这在这里很重要,因为不能推迟副作用。
-
React 文档为我们提供了一个示例,其中在下一次绘制之前计算 DOM 突变,以确保用户不会注意到视觉上的不一致。
-
这可能包括需要即时计算和反馈的特定用例,例如动画或围绕 DOM 移动的东西。对这些用例使用
useEffect
可能会导致不稳定和不一致的体验。
还有一个额外的用例:
- 正如我上面提到的,
useLayoutEffect
相当于 React 的类组件中旧的componentDidMount
生命周期。该钩子可用于帮助您从类组件迁移到功能组件,从而为您提供一对一的替换。但是,这应该是一个临时修复。
外卖
将useEffect
视为您可靠的丰田花冠:可靠、高性能且价格低廉 – 非常适合 99.9% 的用例。另一方面, useLayoutEffect
是一款高端法拉利:速度快、反应灵敏,但运行成本高,仅在速度真正重要时保留 0.1%。
-
useEffect
和useLayoutEffect
都用于操作副作用,但后者允许您在运行时进行更精确的控制。 -
尽可能使用 useEffect 来利用 React 团队的性能优化。
useLayoutEffect
的真正用例很少。仅在 (1) 您需要立即向用户直观地显示副作用时使用,或 (2) 当您临时从componentDidMount
迁移时使用。
原文: https://dev.to/jwwnz/performant-react-101-useeffect-or-uselayouteffect-30b