用过useEffect,useLayoutEffect吗
前言
之前做一个需求,发现存在二次渲染的情况。在这里记录一下useEffect与useLayoutEffect的区别
先看一段代码

打印顺序是什么? 各位小伙伴可以先自行猜想一下。
useEffect
官方定义
在函数组件主体内(这里指在 React 渲染阶段)改变 DOM、添加订阅、设置定时器、记录日志以及执行其他包含副作用的操作都是不被允许的,因为这可能会产生莫名其妙的 bug 并破坏 UI 的一致性。
通俗点来说
useEffect 其实就是让函数组件拥有了生命周期。
useEffect的执行时机
官方定义
与 componentDidMount、componentDidUpdate 不同的是,传给 useEffect 的函数会在浏览器完成布局与绘制之后,在一个延迟事件中被调用。这使得它适用于许多常见的副作用场景,比如设置订阅和事件处理等情况,因为绝大多数操作不应阻塞浏览器对屏幕的更新。
通俗点来讲
不论在面试中,还是工作中。如果有人问你useEffect是如何模拟生命周期的。你都会不假思索的回答出
-
第二个参数传递一个空数组, 模拟
componentDidMount -
第二个参数传递依赖项,模拟
componentDidUpdate -
第二个参数传递一个空数组,并且里面通过return的形式去调用一个方法,模拟
componentWillUnmount
但是useEffect的执行顺序问题,你有想到吗?如果父组件和子组件同时存在useEffect究竟是谁先走?
看一段代码

结果

为什么子组件的useEffect先走?
分析
我们都值得useEffect的执行是在commit之后,React的commit阶段是干什么的?简单来说,就是将DOM渲染到页面上。那么我们是否可以想到,useEffect其实是在页面已经渲染结束后,再触发的?
按照这个执行逻辑来看的话:
-
父组件进入
commit阶段,发现有Son组件需要渲染。 -
开始进行
Son的生命周期,Son进入commit阶段,执行子组件的useEffect,Son渲染结束 -
父组件进行
commit阶段,渲染完成,执行useEffect
useLayoutEffect
官方定义
其函数签名与 useEffect 相同,但它会在所有的 DOM 变更之后同步调用 effect。可以使用它来读取 DOM 布局并同步触发重渲染。在浏览器执行绘制之前,useLayoutEffect 内部的更新计划将被同步刷新
通俗来讲
useLayoutEffect 与 componentDidMount是同步执行的。在commit阶段之前执行,执行顺序优于useEffect

执行顺序

useEffect 与 useLayoutEffect 的区别
useEffect 更改值
-
好处不阻塞浏览器屏幕的渲染更新 -
坏处会造成二次渲染,用户体验不佳

不会做动图。。。。各位大佬自己试一下。。。
会闪烁一下,页面首先展示的是初始值,点击初始值,先更改为我改变了,再更改为我又改变了?
对用户的体验很不好。
useLayoutEffect 更改值
-
好处随componentDidMount同步执行,不会造成二次渲染 -
坏处可能会阻塞浏览器屏幕的渲染更新

页面首先展示的是初始值,点击初始值,更改为我又改变了
最初代码的执行图

可能理解比较浅。后续有更好的理解会修改此文
转载自:https://juejin.cn/post/7081103851884904484