目录
- 前言
- 语法
- `useLayoutEffect `对比 `useEffect`:
- 示例
前言
useLayoutEffect
是 React 中的一个 Hook, 类似于 useEffect
,但有一个关键的区别:它会在所有的 DOM 变更之后同步调用 effect。这意味着它可以读取 DOM 布局并同步重新渲染。如果你需要执行副作用并且这些副作用依赖于 DOM 布局(例如,获取元素的尺寸或位置),你应该使用 useLayoutEffect
。
语法
useLayoutEffect(setup, dependencies?)
useLayoutEffect
的语法和useEffect
一样。
- setup: 处理副作用的函数。
- dependencies: 依赖项。
useLayoutEffect
对比 useEffect
:
- 执行时机:
useLayoutEffect
在浏览器绘制之前同步执行,useEffect
则是在布局会绘制之后执行。 - 执行方式:
useLayoutEffect
同步执行,useEffect
异步执行。 - 堵塞浏览器渲染:
useLayoutEffect
会堵塞,useEffect
不会堵塞。
结论:
若是需要同步读取或更改DOM,或者需要解决页面的闪烁问题,则需要使用useLayoutEffect
。
否则,应该优先考虑使用useEffect
。
下面测试响应的特性:
示例
import { useEffect, useLayoutEffect, useRef } from 'react';
export default function App() {
const div1 = useRef<HTMLDivElement>(null);
const div2 = useRef<HTMLDivElement>(null);
const styles1 = {
width: '100px',
height: '100px',
background: 'red',
opacity: 0
}
const styles2 = {
width: '100px',
height: '100px',
background: 'green',
opacity: 0
}
// 使用 useEffect 实现动画效果
useEffect(() => {
if (div1.current) {
div1.current.style.transition = 'opacity 3s';
div1.current.style.opacity = '1';
}
}, []);
// 使用 useLayoutEffect 实现动画效果
useLayoutEffect(() => {
if (div2.current) {
div2.current.style.transition = 'opacity 3s';
div2.current.style.opacity = '1';
}
}, []);
return (
<div>
<div ref={div1} style={styles1}></div>
<div ref={div2} style={styles2}></div>
</div >
);
}
效果:
useEffect
实现动画的元素有一个透明度渐变的效果。useLayoutEffect
实现动画的元素没有动画效果。
为什么?
我们都知道,CSS的动画在本质上就是某个CSS属性在数值上的变化。
- 使用
useEffect
实现的动画效果- 一开始透明度为0
- 浏览器绘制完成
- 异步执行useEffect,透明度变为1
- 用户看到透明度从0->1的动画效果
- 使用
useLayoutEffect
实现的动画效果- 一开始透明度为0
- DOM更新,同步执行useLayoutEffect,透明度变为1
- 浏览器绘制完成
- 由于绘制已经完成,透明度为1,用户看不到动画效果
希望这篇文章能帮助你更好地理解useLayoutEffect
的使用方法,并为你的 React 项目带来更多的灵感和便利。
如果你有任何问题或建议,欢迎留言交流!