探讨useEffect和useLayoutEffect的区别
2024-05-09
962 字约 4 分钟
...1.背景
面试官问到:请说明下
useEffect和useLayoutEffect的区别。我:一般开发场景都是用的
useEffect,react官方文档上说,两者的使用场景稍微有些不同,但是还是推荐尽量使用useEffect。面试官:不够细节,再说点,摩多摩多。
我:...
2.官网介绍
| 对比 | useEffect | useLayoutEffect |
|---|---|---|
| 简介 | useEffect 是一个 React Hook,它允许你 将组件与外部系统同步。 | useLayoutEffect 是 useEffect 的一个版本,在浏览器重新绘制屏幕之前触发。 |
| aip | useEffect(setup, dependencies?) | useLayoutEffect(setup, dependencies?) |
| 返回值 | undefined | undefined |
3. 对比总结
3.1 useEffect
3.1.1 依赖项对effect执行的影响
-
无依赖项:没有依赖项数组:每次重新渲染后重新运行!
-
错误依赖项:
-
依赖项每次渲染都不同:指定了依赖项数组,你的 Effect 仍循环地重新运行
- => 解决:手动打印依赖项数组进行排查:
console.log([dep1, dep2]);
- => 解决:手动打印依赖项数组进行排查:
-
3.1.2 运行闪烁
我的 Effect 做了一些视觉相关的事情,在它运行之前我看到了一个闪烁
-
产生原因:
useEffect是异步宏任务,在下一轮事件循环才会执行。而GUI渲染和JS线程是互斥的,也就是说,在Effect 运行前,浏览器就已经进行了屏幕渲染,渲染完毕后,useEffect才会被任务队列取出来,开始执行。 -
解决方法:
- 1.在得到正确的数据之前,使用loading
- 2.使用
useLayoutEffect
3.2 useLayoutEffect
3.2.1 依赖项对effect执行的影响
同
useEffect
3.2.2 运行闪烁
useLayoutEffect是同步任务,也就是说,他会在GUI渲染之前触发。
useLayoutEffect内部的代码和所有计划的状态更新阻塞了浏览器重新绘制屏幕。如果过度使用,这会使你的应用程序变慢。如果可能的话,尽量选择useEffect
-
使用场景:
- 在浏览器重绘前计算布局(官网以toolTip组件为例)
function Tooltip() {
const ref = useRef(null);
const [tooltipHeight, setTooltipHeight] = useState(0);
useLayoutEffect(() => {
const { height } = ref.current.getBoundingClientRect();
setTooltipHeight(height);
}, []);
}
4. 一个小demo
准备了一个小demo,可以直观的体现出二者的区别
4.1 部分关键代码:
function App() {
const [num1, setNum1] = useState(0);
const [num2, setNum2] = useState(0);
useEffect(() => {
console.log("b");
setNum1(num1 + 1);
}, []);
useLayoutEffect(() => {
console.log("a");
setNum2(num2 + 1);
}, []);
useEffect(() => {
console.log(num1, num2);
}, [num1, num2]);
return (
<div className="App">
<header className="App-header">
{num1} -- {num2}
</header>
</div>
);
}
4.2 效果展示:
4.3 devtool打印结果:
浏览器设置如下:
- 在
chrome devtools中性能节流配置 cpu六倍降速

4.4 结果分析

5. 最后
nextTick一般用于等待dom操作完成之后马上执行:等待弹窗打开后进行数据回显,这一点来说,与useEffect的用途类似。非交互式的场景下,在执行逻辑不太多的情况下,可以使用useLayoutEffect,避免闪烁,也避免页面白屏时间过长。
6. 参考资料
如果您觉得这篇文章有帮助,请点个赞吧~
相关文章
更多文章 →react2025-12-02
useEffect与useLayoutEffect对比
在 React Hooks 中, 和 都用于处理副作用逻辑,例如订阅、事件监听、DOM 操作等。但它们有着本质性的执行时机差异,这影响到页面渲染、布局抖动、性能表现等关键点。 1\. 执行时机的核心区别 在 React 的渲染流程中: 1. 渲染(Render phase) React 根据 state/props 计算 UI,生成虚拟 DOM,不访问真实 DOM。 2. 提交(Commit phase) React 将虚拟 DOM 变...
学习
react2025-08-03
在 React 中实现倒计时功能会有什么坑
倒计时 倒计时是一个非常常见的业务场景,但是在 React 中实现起来,却不算简单。 首先我们来看这段倒计时代码,它能否正常执行? 来看看实际表现效果 可以看到计时器在不断执行,但是 的值却没有变。 这是一个很经典的问题:React 闭包陷阱 。 我们来详细分析下: 的依赖数组 是空的,这意味着 effect 只会在组件挂载时执行一次,而不会在 状态更新时重新执行。所以 回调函数中捕获的 值始终是初始值 。 这个问题解决起来也很简单,有...
学习面试
react2025-07-30
React性能优化三剑客:memo、useMemo和useCallback详解
前言 在React开发中,性能优化是一个永恒的话题。今天我们就来深入探讨React提供的三个重要性能优化工具: 、 和 ,它们如何帮助我们构建更高效的React应用。 1\. 为什么需要性能优化? 🤔 React的核心机制是当组件的state或props发生变化时,组件会重新渲染。但有时这种重新渲染是不必要的: 父组件更新导致所有子组件重新渲染 ,即使子组件的props没有变化 复杂计算在每次渲染时重复执行 ,消耗大量资源 函数引用在...
学习面试
react2025-06-05
React 中 useDeferredValue 和 startTransition 的核心区别与使用场景
React 中 和 ,两者都用于优化性能,但适用场景和实现方式不同。 核心概念解析 1\. useDeferredValue:延迟值更新 作用 :告诉 React 延迟更新某个值 ,直到所有高优先级渲染任务完成。 适用场景 :当某个值的更新会触发计算密集型渲染(如复杂列表、图表),但需要优先保证其他高优先级 UI(如输入框)的响应。 机制 : 保持旧值显示,后台计算新值。 计算完成后,用新值更新 UI,期间允许用户继续交互。 示例 :...
学习
react2024-12-18
Antd 样式覆盖
目前作者所在的业务正在升级 Antd5.0,不得不说 Antd5.0 真的太香了,但是由于团队的 UE 规范进行了大改版,Antd5.0 所有的 必须对齐最新的规范,因此就需要对 Antd5.0 组件做主题定制。 现状 目前针对项目中使用的 antd 高频组件进行了梳理,并且根据规范基于 design token 对这些高频组件进行样式定制,对于主题色、圆角、边框、字体等用户 高的主题都已经满足团队规范。 虽然 Desig...
学习
react2024-12-06
React 19 终于发布,一大波新功能正式升级
这篇文章主要介绍了 React 19 的新功能,包括 Actions 自动处理数据突变相关状态,新增的 useActionState、useFormStatus、useOptimistic 等 hook,新的 use API 读取渲染资源,新的 React DOM 静态 API 生成静态站点,以及 React 服务器组件中的 RSC 和 RSA 等内容。同时提到后续会分享针对旧版功能的优化和改良。 关联问题: React 19 性能如何...
学习面试
评论
请登录后发表评论
去登录