在 React 官方文档中,useLayoutEffect提到了:
签名与 相同
useEffect,但它在所有 DOM 突变后同步触发。使用它从 DOM 读取布局并同步重新渲染。useLayoutEffect在浏览器有机会绘制之前,内部计划的更新将同步刷新。
此外,useLayoutEffect我们可以在浏览器实际重新绘制之前读取更新的尺寸。
React 是如何做到这一点的?
so @Marko is right.
the browser rendering cycle is split into phases, the relevant ones are:
useLayoutEffect is run after layout but before paint
to achieve that all that you need to do (or what React does) is run the useLayoutEffect functions synchronously after adding or changing elements in the DOM tree.
The browser can't run the painting phase unless you release the thread.
发生的情况是,如果您向浏览器询问元素的大小,它会同步运行布局阶段来给您答案。
这是一个片段和一个沙箱,展示了这个想法:
const conatiner = document.getElementById("container");
function busyWait() {
const array = new Array(100000).fill(Math.random());
let sum = 0;
array.forEach((val, index) => {
const item = array.find((val, i) => i === index);
sum = sum + item;
});
return sum;
}
function addElement() {
const newElement = document.createElement("p");
newElement.innerText =
"this is a paragraph, browser need to measure it to know its size";
if (conatiner) {
conatiner.appendChild(newElement);
console.log(
"layout phase element size",
JSON.stringify(newElement.getBoundingClientRect())
);
const sum = busyWait();
console.log(sum);
setTimeout(() => {
console.log(
"after paint element size",
JSON.stringify(newElement.getBoundingClientRect())
);
}, 10);
}
}
setTimeout(addElement, 100);Run Code Online (Sandbox Code Playgroud)
<div>
we are going to test layout / replaint stages
<div id="container" style="width: 200px;"></div>
</div>Run Code Online (Sandbox Code Playgroud)
如果我没记错的话,它的工作原理是这样的:
回调useLayoutEffect将在步骤 3 和 4 之间触发。
| 归档时间: |
|
| 查看次数: |
795 次 |
| 最近记录: |