当前位置: 首页 > news >正文

前端 - React - - useEffect和useLayoutEffect的区别

useEffect和useLayoutEfeect都是处理副作用函数,他俩的区别是在执行时间与事件机制上。

1. 核心区别:

  • useEffect(异步执行):在浏览器绘制完成之后异步执行。它不会阻塞浏览器的视觉更新,适合用于获取数据、事件绑定、日志记录等不直接影响当前帧 UI 的操作。

  • useLayoutEffect(同步执行):在浏览器绘制之前同步执行。它会阻塞浏览器的渲染,直到回调执行完毕。适合用于需要直接操作 DOM 样式、测量 DOM 尺寸,且需要避免 UI 闪烁的场景。

2. 分步分析执行时机

为了直观理解,我们看一下 React 组件更新时的完整时间线:

  1. 触发更新:State 或 Props 改变。

  2. Render 阶段:React 执行组件函数,计算 Virtual DOM。

  3. Commit 阶段:React 将 Virtual DOM 变更映射到真实的 DOM 节点(此时 DOM 已更新,但屏幕尚未绘制)。

  4. useLayoutEffect执行(同步阻塞):React 在此处立即执行所有useLayoutEffect回调。

  5. 浏览器绘制(Paint):浏览器终于将 DOM 节点绘制到屏幕上(变成像素)。

  6. useEffect执行(异步):React 在浏览器绘制完成后,利用requestIdleCallback或微任务机制,延迟执行useEffect回调。

核心结论useLayoutEffect执行时,你可以拿到最新的 DOM 节点,但屏幕还是旧的(还没画);useEffect执行时,屏幕已经变成新的了。

  • 常见问题:使用useEffect时,会出现页面闪烁问题:

假设你有一个组件,渲染时依赖某个 DOM 节点的宽度,且该宽度需要动态计算后设置高度。

如果用useEffect(错误示例):

function BrokenComponent() { const ref = useRef(); useEffect(() => { const height = ref.current.getBoundingClientRect().width; ref.current.style.height = `${height}px`; // 修改 DOM }, []); return <div ref={ref}>内容</div>; }

页面会先渲染旧的高度(比如高度为0),然后瞬间“跳”到计算后的新高度。用户会看到明显的抖动或闪烁

如果用useLayoutEffect(正确示例):

function FixedComponent() { const ref = useRef(); useLayoutEffect(() => { const height = ref.current.getBoundingClientRect().width; ref.current.style.height = `${height}px`; }, []); return <div ref={ref}>内容</div>; }

React 在绘制前就修改了高度,浏览器绘制时直接使用了最终尺寸,用户看到的是稳定且平滑的界面。

注意:在 SSR 环境下(服务端渲染),useLayoutEffect会抛出警告(Warning:useLayoutEffectdoes nothing on the server)。因为在服务端没有 DOM 和 Paint 的概念,React 会自动降级为useEffect

http://www.gsyq.cn/news/1589712.html

相关文章:

  • 从词向量到大模型:NLP 技术演进浅记
  • 你的 AI 助手为什么总是 “掉线“?真正的原因不在网络
  • 终极iOS激活锁绕过指南:免费解锁iPhone 15-16的完整解决方案
  • 终极Windows系统优化指南:Win11Debloat让你的电脑重获新生
  • SQL注入攻防实战:从手工探测到自动化利用与防御实践
  • 高灵敏安全触边,消除设备夹手隐患
  • 基座模型切换实战指南:Grok-4推理优化与系统适配
  • 从噪音困扰到静音享受:如何用FanControl为Windows电脑定制专属风扇策略
  • 终极Office激活指南:3分钟解锁Microsoft 365完整功能
  • 终极MPV播放器懒人包:10分钟打造专业级视频播放体验
  • 终极指南:让微信网页版在任何浏览器中完美运行的简单方法
  • 当工具越来越多,Prompt 需要分层管理
  • EasyOCR微调实战:零基础提升垂直场景OCR准确率
  • 英雄联盟智能助手:5个功能彻底改变你的游戏体验
  • 从高斯曲率到Morse-Bott理论:能量函数如何刻画曲面形态
  • 开源PLC编程终极指南:如何用OpenPLC Editor零成本掌握工业自动化
  • 【小白向】低配电脑也能流畅跑,虾壳云一键部署 OpenClaw v2.7.9 适配教程(最新安装包)
  • 【学术干货】从「预测器」到「发现工具」:清华UniCM如何让AI真正理解全球气候系统
  • 别天天只知道群发!教你 搭建个人微信增量语料库,低成本喂饱本地大模型
  • Django毕业设计-基于 Django 的可视化人工智能科普平台设计与实现 基于 Django 的 AI 知识可视化科普平台(源码+LW+部署文档+全bao+远程调试+代码讲解等)
  • 时间复杂度和空间复杂度
  • LangGraph与LLM连接实战:State数据契约与消息适配器设计
  • NYFEA徕飞重磅推出SN74LVC系列逻辑芯片
  • OBS实时字幕插件完整指南:5分钟实现直播字幕功能
  • LLM 驱动的智能工作流引擎:从 Prompt 编排到 DAG 调度的工程实践
  • LPC315x微控制器PCM/IOM接口配置与SysCReg寄存器详解
  • 计算机毕业设计之“汉画像砖” 文化宣传网站
  • 新手必看的美食视频背景音乐选曲指南:5个高性价比素材网站深度评测
  • iPhone本地大模型实战:Gemma 2量化部署与Core ML优化指南
  • 网站有流量为什么没有询盘?很多时候不是SEO没用,而是页面没接住客户