useLayoutEffect Vs useEffect
useLayoutEffect
和 useEffect
都是 React 提供的 Hook,用于处理副作用,但它们在执行时机上有重要区别。
主要区别
特性 | useEffect |
useLayoutEffect |
---|---|---|
执行时机 | 在浏览器绘制之后异步执行 | 在浏览器绘制之前同步执行 |
对用户的影响 | 可能导致布局闪烁 | 阻止浏览器绘制直到 effect 完成 |
使用场景 | 数据获取、订阅等 | 需要同步读取/操作 DOM 的情况 |
性能影响 | 对渲染性能影响较小 | 可能阻塞渲染,导致性能问题 |
详细解释
1. 执行时机
useEffect
:- 在组件渲染到屏幕之后执行
- 异步执行,不会阻塞浏览器绘制
useLayoutEffect
:- 在 React 计算完 DOM 变更后,但在浏览器实际绘制之前执行
- 同步执行,会阻塞浏览器绘制
2. 使用场景示例
适合 useLayoutEffect
的情况:
1 | function Tooltip() { |
适合 useEffect
的情况:
1 | function UserProfile({ userId }) { |
3. 为什么选择其中一个而不是另一个
使用
useLayoutEffect
当:- 你需要读取 DOM 布局并同步触发重渲染
- 你需要执行 DOM 操作以避免视觉闪烁或不一致
使用
useEffect
当:- 你的副作用不需要与 DOM 交互
- 你的代码可以容忍短暂的布局不一致
- 你需要执行数据获取或订阅等异步操作
重要注意事项
**服务端渲染 (SSR)**:
useLayoutEffect
在 SSR 期间会导致警告(因为它不能在服务端执行)- 在 SSR 应用中,React 建议先用
useEffect
,如果发现问题再考虑useLayoutEffect
性能影响:
- 过度使用
useLayoutEffect
可能导致性能问题,因为它会阻塞渲染 - 大多数情况下
useEffect
是更好的默认选择
- 过度使用
执行顺序:
- 在同一个组件中,
useLayoutEffect
总是比useEffect
先执行
- 在同一个组件中,
经验法则
- 默认使用
useEffect
- 这是最安全的选择 - 只有在需要同步测量或操作 DOM 时才使用
useLayoutEffect
- 如果你不确定,先尝试
useEffect
,只有出现视觉问题时再考虑useLayoutEffect