useEffect有时会在油漆前启动

useEffect should run after paint to prevent blocking the update. But did you know it’s not really guaranteed to fire after paint? Updating state in useLayoutEffect makes every useEffect from the same render run before paint, effectively turning them into layout effects. Confusing? Let me explain.

useEffect 应该在paint之后运行,以防止阻塞更新。但是你知道吗,它并不能保证在绘制之后启动?在useLayoutEffect 中更新状态会使同一渲染中的每个useEffect 绘制运行,有效地将它们变成了布局效果。令人困惑吗?让我解释一下。

In a normal flow, react updates go like this:

在一个正常的流程中,反应更新是这样的。

  1. React stuff: render virtual DOM, schedule effects, update real DOM
  2. React的东西:渲染虚拟DOM,安排效果,更新真实DOM
  3. Call useLayoutEffect
  4. 致电useLayoutEffect
  5. React releases control, browser paints the new DOM
  6. React释放控制,浏览器绘制新的DOM
  7. Call useEffect
  8. 致电useEffect

React docs don’t say when, exactly, useEffect fires — it happens, quote, after layout and paint, during a deferred event. I always assumed it was a setTimeout(effect, 3), but it appears to use a MessageChannel trick, which is neat.

React文档并没有说useEffect到底什么时候发生--它发生在布局和绘制之后,在一个延迟事件中。我一直认为它是一个setTimeout(effect, 3) ,但它似乎使用了一个MessageChannel ,这很好。

There is, however, a more interesting passage in the docs:

然而,在文件中,有一段更有趣的内容。

Although useEffect is deferred until after the browser has painted, it’s guaranteed to fire before any new renders. React will always flush a previous render’s effects before starting a new update.

虽然useEffect被推迟到浏览器画完之后,但它保证在任何新的渲染之前启动。React在开始新的更新之前,总是会刷新之前渲染的效果。

This is a good guarantee — you can be sure no updates are missed. But it also implies that sometimes the effect fires before paint. If a) effects are flushed before a new update starts, and b) an update can start before paint, e.g. when triggered from useLayoutEffect, then the effect must be flushed before that update, which is before paint. Here’s a timeline:

这是一个很好的保证--你可以确定没有错过任何更新。但它也意味着有时效果会在刷新前启动。如果a)效果在新的更新开始前被刷新,b)更新可以刷新开始,例如当从useLayoutEffect那么效果必须该更新被刷新,也就是刷新。这里有一个时间线。

  1. React update 1: render virtual DOM, schedule effects, update DOM
  2. React更新1:渲染虚拟DOM,安排效果,更新DOM
  3. Call useLayoutEffect
  4. 致电useLayoutEffect
  5. Update ...
开通本站会员,查看完整译文。

Accueil - Wiki
Copyright © 2011-2024 iteam. Current version is 2.137.1. UTC+08:00, 2024-11-15 12:42
浙ICP备14020137号-1 $Carte des visiteurs$