React:React 如何确保在浏览器有机会绘制后调用 useEffect?

IT技术 javascript reactjs
2021-05-10 23:47:05

useLayoutEffect 的文档说:

在浏览器有机会绘制之前, useLayoutEffect 内计划的更新将同步刷新。

useEffect 的文档说:

与 componentDidMount 和 componentDidUpdate 不同,传递给 useEffect 的函数在布局和绘制之后在延迟事件期间触发。

React 如何检查布局和绘制何时发生以及何时是调用 useEffect 的正确时间?我经常在这种情况下使用 setTimeout 0 的一种技巧,但我有兴趣了解 React 如何实现这一点?(设置超时,请求动画帧?)

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不能单独使用,因为它在 repaint 之前被触发现在,如果您在使用 重绘之前将消息发布到页面本身postMessage,则该回调将在重绘后直接运行。

 const channel = new MessageChannel();

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

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