Open jtwang7 opened 3 years ago
useLayoutEffect
与 useEffect
使用类似,其区别在于:
useEffect 在全部渲染完毕后(布局+绘制)异步执行;useLayoutEffect 在浏览器布局(layout)之后,绘制(painting)之前同步执行。
useLayoutEffect 使我们可以在 layout 后更正布局,然后再绘制到浏览器上。
读取 DOM 布局并同步触发重渲染。在浏览器执行绘制之前,useLayoutEffect 内部的更新计划将被同步刷新。
由于 useLayoutEffect 会在浏览器 layout 之后同步执行,因此它会阻塞浏览器视图的更新。(假设它占用较长时间,页面则出现卡死现象)
除非需要在更新前读取 DOM 布局,否则尽可能使用标准的 useEffect 以避免阻塞视图更新。
React - Hooks (useEffect)
参考文章:
effect 副作用
副作用指那些没有发生在数据向视图转换过程中的逻辑。如:
useEffect
在 Hooks 未被提出之前,改变 dom 、发送 ajax 请求以及执行其他包含副作用的操作只能在生命周期函数中使用,函数组件中由于没有生命周期函数,因此不能添加副作用。 useEffect 的出现,给函数组件增加了操作副作用的能力。它跟 class 组件中的 componentDidMount、componentDidUpdate 和 componentWillUnmount 具有相同的用途,只不过被合并成了一个 API。
语法
useEffect(func)
useEffect 接收一个函数,传给 useEffect 的函数会在浏览器完成布局与绘制之后,在一个延迟事件中被调用。 此外 useEffect 接受的函数还可以返回一个清除函数。清除函数会在组件卸载前执行,如果组件重新渲染,则在执行下一个 effect 之前,上一个 effect 就已被清除。useEffect 的执行时机
useEffect 在第一次渲染之后和每次更新之后都会执行,与 componentDidMount、componentDidUpdate 不同的是,传给 useEffect 的函数会在浏览器完成布局与绘制之后,在一个延迟事件中被调用。这意味着 useEffect 不会阻塞浏览器对屏幕的更新。
虽然 useEffect 会在浏览器绘制后延迟执行,但会保证在任何新的渲染前执行。在开始新的更新前,React 总会先清除上一轮渲染的 effect。
并非所有 effect 都可以被延迟执行。例如,一个对用户可见的 DOM 变更就必须在浏览器执行下一次绘制前被同步执行,这样用户才不会感觉到视觉上的不一致。React 为此提供了一个额外的 useLayoutEffect Hook 来处理这类 effect。它和 useEffect 的结构相同,区别只是调用时机不同。
useEffect 的依赖项数组
每次组件渲染都会执行其内部定义的 useEffect,我们可以设置依赖项数组,来保证某个 useEffect 只监测特定值的变化,当某些特定值在两次重渲染之间没有发生变化(Object.is)时,React 会跳过对该 useEffect 的调用。
useEffect 执行顺序
使用 Hook 其中一个目的就是要解决 class 中生命周期函数经常包含不相关的逻辑,但又把相关逻辑分离到了几个不同方法中的问题。Hook 允许我们按照代码的用途分离他们,React 将按照 effect 声明的顺序依次调用组件中的每一个 effect。