【问题标题】:React: How does React make sure that useEffect is called after the browser has had a chance to paint?React:React 如何确保在浏览器有机会绘制之后调用 useEffect?
【发布时间】:2023-03-28 07:31:01
【问题描述】:

useLayoutEffect 的文档说:

在 useLayoutEffect 中安排的更新将被刷新 同步,在浏览器有机会绘制之前。

useEffect 的文档说:

与componentDidMount和componentDidUpdate不同,该函数通过 在延迟事件期间,在布局和绘制之后触发 useEffect。

React 如何检查布局和绘制何时发生以及何时调用 useEffect ? 我经常在这种情况下使用 setTimeout 0 的 hack,但我有兴趣了解 React 如何实现这一点? (SetTimeout, requestAnimationFrame ?)

【问题讨论】:

  • 我只是想通了反应源,但我还是找不到相关的部分......我找到的只是ReactDOM.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED :)

标签: javascript reactjs


【解决方案1】:

他们使用postMessage(结合requestAnimationFrame):

  // We use the postMessage trick to defer idle work until after the repaint.

发现于 React/scheduler/src/forks/SchedulerHostConfig.default.js

setTimeout 不能使用,因为如果递归使用它将被限制。 requestAnimationFrame 不能单独使用,因为它会在重绘之前触发。现在,如果您在重绘之前使用 postMessage 向页面本身发布一条消息,那么该回调将在重绘之后直接运行。

 const channel = new MessageChannel();

 channel.port1.onmessage = function() {
  console.log("after repaint");
 };

 requestAnimationFrame(function () {
   console.log("before repaint");
   channel.port2.postMessage(undefined);
 });

【讨论】:

  • setTimeout 会有什么问题?是否存在我们希望递归调用此功能的情况?如果它节流,“重绘后”调用是否会延迟?但是我们仍然可以确定 setTimeout 会在绘制之后发生吗?
  • setTimeout 回调与绘画无关,这就是 requestAnimationFrame 的用途。但是它不能像postMessage 那样使用,因为setTimeout(callback, 0) 会被限制在几毫秒内。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-28
相关资源
最近更新 更多