编辑
2025-03-12
React
00
请注意,本文编写于 31 天前,最后修改于 25 天前,其中某些信息可能已经过时。

目录

1. 执行时机
2. 对用户体验的影响
示例:修改 DOM 样式
3. 适用场景
示例:测量元素尺寸
4. 性能影响
5. 服务端渲染(SSR)
6. 代码示例对比
总结

在最近一次面试中被问到,我印象中好像从来没用过useLayoutEffect,就没答上来。但是看名字应该是跟布局相关的,而且跟useEffect会有类似的作用。

React 中,useEffectuseLayoutEffect 都是用于处理副作用的 Hooks,但它们的执行时机和对渲染流程的影响有显著区别。以下是两者的核心差异及使用场景:

1. 执行时机

Hook执行实际
useEffect异步执行:在浏览器完成布局和绘制(Paint)后触发。
useLayoutEffect同步执行:在 React 完成 DOM 更新后、浏览器绘制前触发,会阻塞浏览器渲染。

React 组件更新 → 计算 DOM 变更 → 更新 DOM → [useLayoutEffect 执行] → 浏览器绘制 → [useEffect 执行]

2. 对用户体验的影响

Hook用户感知
useEffect副作用可能稍后执行,用户可能先看到未更新的界面,再看到更新后的内容(短暂闪烁)。
useLayoutEffect副作用在绘制前完成,用户直接看到最终结果,避免视觉不一致。

示例:修改 DOM 样式

js
// 使用 useEffect(可能闪烁) useEffect(() => { const element = document.getElementById("my-element"); element.style.color = "red"; // 浏览器可能先绘制默认颜色,再变红 }, []); // 使用 useLayoutEffect(无闪烁) useLayoutEffect(() => { const element = document.getElementById("my-element"); element.style.color = "red"; // 在绘制前完成修改 }, []);

3. 适用场景

Hook典型场景
useEffect数据获取(API 请求)/ 订阅事件(如 WebSocket) / 不需要同步 DOM 的操作
useLayoutEffect测量 DOM 元素尺寸/位置(如动态调整布局) / 同步修改 DOM 样式以避免闪烁

示例:测量元素尺寸

js
useLayoutEffect(() => { const element = document.getElementById("my-element"); const width = element.offsetWidth; setElementWidth(width); // 在绘制前获取并更新尺寸 }, []);

4. 性能影响

  • useEffect

异步执行,不会阻塞渲染,适合大多数场景,尤其是耗时操作(如网络请求)。

  • useLayoutEffect

同步执行,若副作用逻辑复杂可能导致渲染延迟,需谨慎使用。

5. 服务端渲染(SSR)

  • useEffect

无此问题,适合 SSR 环境。

  • useLayoutEffect

在服务端渲染时,React 会发出警告(因为其逻辑无法在服务端执行),需替换为 useEffect 或在客户端渲染后执行。

6. 代码示例对比

场景:点击按钮后动态调整元素高度

js
// 使用 useEffect(可能闪烁) function Component() { const [height, setHeight] = useState(0); const ref = useRef(); useEffect(() => { ref.current.style.height = "100px"; // 可能先渲染默认高度,再调整 }, []); return <div ref={ref}>Height: {height}px</div>; } // 使用 useLayoutEffect(无闪烁) function Component() { const [height, setHeight] = useState(0); const ref = useRef(); useLayoutEffect(() => { ref.current.style.height = "100px"; // 在绘制前完成调整 }, []); return <div ref={ref}>Height: {height}px</div>; }

总结

维度useEffectuseLayoutEffect
执行时机异步(绘制后)同步(绘制前)
用户体验可能闪烁无闪烁
性能影响可能阻塞渲染
适用场景数据获取、订阅事件等异步操作同步 DOM 操作(测量、调整样式)
SSR 兼容性兼容需特殊处理
  • 优先使用 useEffect
  • 仅在需要同步操作 DOM 或避免视觉不一致时使用 useLayoutEffect
如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:CreatorRay

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!