useLayoutEffect和useEffect用法基本相同
区别:
| 区别 | useLayoutEffect | useEffect |
|---|---|---|
| 执行时机 | 浏览器完成布局和绘制之前执行副作用 | 浏览器完成布局和绘制之后执行副作用 |
| 执行方式 | 同步执行 | 异步执行 |
| DOM渲染 | 阻塞DOM渲染 | 不阻塞DOM渲染 |
应用场景
- 需要同步读取或更改DOM:例如,你需要读取元素的大小或位置并在渲染前进行调整。
- 防止闪烁:在某些情况下,异步的useEffect可能会导致可见的布局跳动或闪烁。例如,动画的启动或某些可见的快速DOM更改。
- 模拟生命周期方法:如果你正在将旧的类组件迁移到功能组件,并需要模拟 componentDidMount、componentDidUpdate和componentWillUnmount的同步行为。
测试DOM阻塞
下面这个例子展示了 useLayoutEffect 和 useEffect 在DOM渲染时的区别。useLayoutEffect 会阻塞DOM渲染,而 useEffect 不会。
import React, { useLayoutEffect, useEffect, useState } from 'react';
function App() {
const [count, setCount] = useState(0)
//不阻塞DOM
// useEffect(() => {
// for (let i = 0; i < 50000; i++) {
// //console.log(i);
// setCount(count => count + 1)
// }
// }, []);
//阻塞DOM
// useLayoutEffect(() => {
// for (let i = 0; i < 50000; i++) {
// //console.log(i);
// setCount(count => count + 1)
// }
// }, []);
return (
<div>
<div>app </div>
{
Array.from({ length: count }).map((_, index) => (
<div key={index}>{index}</div>
))
}
</div>
);
}
export default App;