【问题标题】:Is `useLayoutEffect` preferable to `useEffect` when reading layout?阅读布局时,`useLayoutEffect` 是否优于 `useEffect`?
【发布时间】:2021-05-14 20:19:28
【问题描述】:

useLayoutEffectuseEffect 的一个区别是 useLayoutEffect 将在 DOM 突变之后和浏览器绘制阶段之前同步触发。 (Reference)

但是,我遇到了一些文章,它们似乎都建议使用useLayoutEffect 进行阅读布局。

React docs:

签名与 useEffect 相同,但它会在所有 DOM 突变后同步触发。 使用它从 DOM 中读取布局并同步重新渲染。在 useLayoutEffect 中安排的更新将在浏览器有机会绘制之前同步刷新。

Kent C.Dodds:

useLayoutEffect:如果您需要改变 DOM 和/或确实需要执行测量

Ohans Emmanuel:

在可能的情况下,如果您希望在浏览器绘制过程的处理中不引人注目,请选择 useEffect Hook。在现实世界中,这通常是大多数时候! 好吧,除非你从 DOM 中读取布局或做一些需要尽快绘制的与 DOM 相关的事情。

据我了解,当useEffect 被触发时,浏览器已经通过了布局和绘制阶段,所以在useEffect 中读取布局应该是完全可以的。

所以我的问题是:阅读布局时,useLayoutEffect 是否优于 useEffect,如果是,为什么?假设我只是阅读了布局,并没有在效果中执行任何额外的状态更改。

【问题讨论】:

  • 对于 reading - 它并不可取,对于 attaching 它确实如此,与文档中提到的相同

标签: reactjs react-hooks use-effect


【解决方案1】:

下图总是可以帮助我可视化钩子的流程,也可以让您澄清为什么推荐 useLayoutEffect 而不是 useEffect 用于基于 DOM 的操作(您的目标是可以在当前浏览器之前更新的东西油漆)

图表链接 - https://github.com/donavon/hook-flow

【讨论】:

  • 感谢您推荐此图表。
【解决方案2】:

答案取决于您作为开发人员认为“更受欢迎”的内容。在您的问题useLayoutEffect 保证您将在突变之前看到布局的上下文中,useEffect 向您展示了之后会发生什么。

【讨论】:

  • “首选”是指在阅读布局时它有什么优势(在useLayoutEffectuseEffect 之间)?
  • @dongnhan 我会说'useEffect'在你的情况下使用更安全,因为它不会阻止渲染。而且您将确信您正在获取最新的 DOM 数据。
  • 我认为你有关于渲染阻塞的观点。关于获取最新的DOM数据,在布局阶段,浏览器已经正确计算了所有的空间,然后在绘制阶段,浏览器只是填充像素,所以我认为获取最新的DOM数据是不正确的. developers.google.com/web/fundamentals/performance/…
  • @dongnhan 我认为您误解了浏览器生命周期和 React 生命周期。所有 React 的东西都包含在 javascript 阶段,大小计算发生在 React 将更改推送到 dom 之后。而“useLayoutEffect”发生在两者之间,阻止了 react 发布 DOM 更新。 'useEffect' 在所有 DOM 更新完成后发生。
  • 嗨,我想我明白了。通过“获取最新的 DOM 数据”,useEffect 会更好,以防您 useLayoutEffect 中执行一些突变(因为 useLayoutEffect 中的更改将被刷新,到时候 @987654329 @ 被调用,一切都已设置和绘制)。我想我需要澄清一下我最初的问题,我只想强调useEffectuseLayoutEffect 中的“阅读布局”,并认为我没有执行任何突变。
【解决方案3】:

如果钩子中没有 DOM 操作代码,只读取布局 useEffect 就可以了。

如果您在 useEffect 中有 DOM 操作代码并看到屏幕闪烁,请将此代码移至 useLayoutEffect。

是这样的:

  1. 渲染
  2. useLayoutEffect(在所有 DOM 突变后同步)
  3. 油漆
  4. 使用效果

【讨论】:

    猜你喜欢
    • 2012-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-05
    • 1970-01-01
    • 2012-09-15
    • 2023-03-10
    相关资源
    最近更新 更多