ReactHook - useEffect、useLayoutEffect

发布时间:2026/11/5 9:36:29

ReactHook - useEffect、useLayoutEffect useEffect作用推迟代码执行渲染完成之后再执行常用于 数据读取完成移除 - 组件卸载的时候做一些清理的工作例如移除定时器、事件监听器等有关组件卸载触发时机当组件从 DOM 中移除时会触发useEffect里返回的函数useEffect里的内容不会执行执行也没有意义了。当组件出现在DOM中时会执行useEffect里的代码useEffect里返回的函数不执行。importReact,{useState,useEffect}fromreact;functionTimerComponent(){const[count,setCount]useState(0);useEffect((){consttimersetInterval((){setCount(prevCountprevCount1);},1000);// 返回的函数将在组件卸载时执行return(){clearInterval(timer);console.log(Timer cleared);};},[]);// 空依赖数组effect 只在挂载和卸载时运行returndivTimer:{count}/div;}exportdefaultTimerComponent;该行为是模拟了componentWillUnmount常用于清理操作例如取消网络请求、清除计时器或移除事件监听器。补充何时执行componentWillUnmount组件从页面移除当用户导航到另一个页面或条件渲染使得组件不再显示时componentWillUnmount 会被调用。在上面的例子中当 TimerComponent 被移除时计时器会被清除。父组件卸载如果父组件卸载了所有子组件也会卸载它们的 componentWillUnmount 也会被调用。第二个参数来模拟生命周期。对于缓存的对象来说因为每次函数都重新执行因此对象的引用会变所以useEffect第二个参数缓存的是引用的地址。useEffect存在一种bail out(保释) / (补救)机制当你尝试设置相同的状态仅仅让你把函数执行完但不会再触发effect。同理在class组件中的setState也是一样。setStatestate设置重复的值 —— 只会重复渲染一次 11. 推迟代码执行例如上面其实本来就是一种错误的写法只是React官方帮你兜了个底。正确的做法是2. 完成移除 定时器、监听functionHOC(){const[count,setCount]useState(0);useEffect((){console.log(创建)return(){console.log(销毁)}});return(button onClick{()setCount(count1)}按钮/button/)}exportdefaultHOC;当状态变化的时候重新渲染重新渲染导致useEffect执行前提是没有依赖项。在第一次刷新的时候不执行useEffect返回的函数只执行useEffect里的内容。后面状态变化导致重新渲染的时候会优先执行useEffect返回的函数然后再执行useEffect里的内容。例如页面初始化时第一次点击按钮时useEffect - clean-up阶段有两个删除组件重新渲染当前组件1. 第一个删除组件的时候执行注意useEffect里的回调如果有返回值的话必须是一个函数。会先执行这个return函数例如下面的代码。2. 第二个重新渲染的时候执行开发环境StrictMode下useEffect跑两遍在开发环境中React 可能会让组件经历类似下面的流程第一次挂载 mount - 执行 useEffect 立刻模拟卸载 unmount - 执行 useEffect 的 cleanup 清理函数 再次挂载 mount - 再执行 useEffect所以你会看到useEffect(() { console.log(effect run); return () { console.log(cleanup); }; }, []);开发模式下可能打印effect run cleanup effect run但这不是 bug也不是生产环境行为。这是 React 在开发环境下故意做的检查。注意错误的使用state会导致资源泄露例如1.某种异步操作开始——非常长2.组件已经被卸载了3.setState - 资源(内存泄露、socket泄露主要是内存泄露)泄露代码如下会报如下警告⚠️Warning: Can’t perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.in Unknown (at App.js:13)解决方法3. 第三种 第二个参数来模拟生命周期。useEffect选择执行当a变化才打印effect a当b变化才打印effect b类似于[a]这种形式 官方叫做 ”跳过“useEffect模拟生存周期函数useEffect(fn, [值]);如componentDidMountuseEffect() 的callback返回函数的case其实是根据当前操作来的是添加移除定时器还是添加移除dom执行效果是不一样的具体可以参考useEffect() 有始有终useLayoutEffect是 React 提供的一个 Hook你可以把它理解为**“在浏览器把画面绘制出来之前React 给你的最后一次修改 DOM 的机会”**。它的功能签名和useEffect几乎一模一样但核心区别在于执行时机。useEffect vs useLayoutEffect为了理解它我们需要看浏览器的渲染流程React 更新 DOM→useLayoutEffect 执行→浏览器绘制 (Paint)→useEffect 执行特性useEffect (常用)useLayoutEffect (特殊)执行时机浏览器绘制完成后异步执行浏览器绘制之前同步执行视觉体验如果修改了布局用户可能会看到闪烁先显示旧位置再跳到新位置用户看不到中间状态直接看到最终结果无闪烁性能影响不阻塞浏览器绘制性能较好会阻塞浏览器绘制用多了会导致页面卡顿比喻演出开始后你在后台改道具幕布拉开前你冲上去把道具摆好 什么时候必须用 useLayoutEffect只有当你需要读取 DOM 布局如宽高、位置并立即同步修改 DOM时才使用它。主要用于解决“视觉闪烁”问题。典型场景 1防止弹窗/气泡定位闪烁假设你要做一个 Tooltip气泡提示它需要显示在按钮的上方。如果用useEffect页面先渲染 Tooltip 在默认位置比如左上角 - 浏览器绘制 -useEffect计算按钮位置 - 修改 Tooltip 位置 - 用户看到 Tooltip“闪”了一下跳到了按钮上方。如果用useLayoutEffectReact 更新 DOM -useLayoutEffect立即计算位置并修改 - 浏览器绘制直接画出正确位置的 Tooltip - 用户完全感觉不到位置修正的过程。典型场景 2根据内容调整布局比如你需要根据一个容器的实际宽度来决定里面放几个卡片。你需要先测量容器宽度再决定渲染逻辑这个过程必须在绘制前完成。典型场景 3强制同步滚动比如进入聊天室你希望滚动条直接到底部不想让用户看到“先在顶部再跳到底部”的过程。⚠️ 什么时候不要用绝大多数情况下请优先使用useEffect。以下场景不要用useLayoutEffect数据请求 (API 调用)事件订阅/监听日志记录、埋点写入 LocalStorage任何不依赖 DOM 测量的操作因为在这些场景下使用useLayoutEffect只会徒增性能开销阻塞页面渲染带来卡顿风险。 总结口诀“涉及测量和布局修正怕闪就用useLayoutEffect其他所有副作用统统用useEffect。”useLayoutEffect是 React16.8.0版本引入的。
延伸阅读

更多相关文章

2026/11/1 5:18:34

LPrint终极指南:5分钟搞定全平台标签打印的完整解决方案

LPrint终极指南:5分钟搞定全平台标签打印的完整解决方案 【免费下载链接】lprint A Label Printer Application 项目地址: https://gitcode.com/gh_mirrors/lp/lprint 在数字化办公和物流管理中,标签打印需求无处不在,但跨平台兼容性问…

2026/11/5 7:31:17

Nemotron-CLIMB代理模型实战教程:从下载到推理的完整流程

Nemotron-CLIMB代理模型实战教程:从下载到推理的完整流程 【免费下载链接】nemotron-climb-proxy-models 项目地址: https://ai.gitcode.com/hf_mirrors/nvidia/nemotron-climb-proxy-models Nemotron-CLIMB代理模型是由NVIDIA开发的轻量级语言模型&#xf…

2026/11/5 9:33:33

live555 MP4点播实战:自定义FramedSource实现RTSP流媒体

简介:面向具备C基础、希望掌握流媒体点播实现的中高级开发者,这份资源围绕live555 Media Server与MP4点播展开,可用于搭建RTSP点播服务、理解RTP封装与音视频同步机制,也可作为ffmpeg解析MP4元数据、处理客户端Range请求与断点续传…

2026/11/5 9:33:33

Linux部署Django商城:环境分层、Gunicorn+Nginx与避坑指南

简介:本资源是一套面向中高级Python Web开发者的学习型Django电商项目,聚焦Linux生产环境下的大型前后端商城完整搭建实践,适用于希望系统掌握Django企业级开发、部署与架构设计的工程师与进阶学习者。压缩包共204个文件,涵盖99个…

2026/11/5 9:33:33

IdentityServer4 统一认证中心:OAuth2.0/OIDC 落地

接手一套跑了两年的业务系统时,最先让人头疼的往往不是业务代码,而是散落在各处的登录逻辑。三个前端应用各自一套账号体系,两个后端服务各写一份令牌校验,移动端又是第三种登录方式,改一次密码复杂度策略,前后要发六个版本&#…

2026/11/5 9:33:33

具身智能操作系统:从理论到工业实践的突破

1. 具身智能操作系统的概念与价值具身智能操作系统(Embodied AI OS)是近年来人工智能领域最具突破性的研究方向之一。与传统的AI系统不同,它强调智能体在物理环境中的具身化(Embodiment)特性,通过感知-行动…

2026/11/5 9:33:33

SSTI模板注入入门:原理、引擎判断、绕过与代码审计防御

SSTI 这几个字母我第一次看到的时候,还以为是什么新的传输协议缩写,翻了几篇入门题解才反应过来,它说的是服务端模板注入(Server-Side Template Injection)。这套 ctfshow web 入门题单里的 SSTI 系列,基本…

2026/11/5 9:28:27

工业级推荐系统架构设计与工程实践

1. 推荐系统架构全景解析 现代推荐系统早已超越了简单的"用户喜欢什么就推什么"的初级阶段。一个成熟的工业级推荐系统通常采用分层处理架构,就像工厂的流水线一样,每个环节各司其职又紧密配合。这种设计不仅能处理海量数据,还能在…

2026/11/4 12:38:23

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/4 21:04:25

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/5 0:02:07

多智能体协作系统架构设计与实践优化

1. 多智能体协作系统的时代背景2017年Transformer架构的诞生彻底改变了人工智能的发展轨迹。当行业还沉浸在单一大模型带来的性能突破时,Anthropic的研究团队已经将目光投向了更前沿的领域——如何让多个智能体通过协作产生超越单体能力的系统智能。这就像交响乐团中…

2026/11/5 0:02:07

大模型系统性入门实战指南:从原理到部署微调的全链路路线

提到大模型的系统性入门,我先说个结论:这事真不难,难的是资料太散、路线太多,今天这个框架明天那个工具,新人很容易在“收藏夹吃灰”和“教程看到一半放弃”之间反复横跳。市面上关于大模型的内容少说有几十万篇&#…

2026/11/5 0:02:07

鸿蒙文件系统沙箱机制解析与开发实践

1. 鸿蒙文件系统沙箱机制深度解析作为一名从Android转向鸿蒙开发的工程师,我深刻体会到文件系统访问是迁移过程中最先遇到的"拦路虎"。在Android上运行良好的文件读写代码,在鸿蒙真机环境却频频出现文件写入后神秘消失或直接抛出权限拒绝错误的…

2026/11/4 12:38:23

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/4 21:04:25

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑