Re: 新手让网页 act 起来: Day26 - React Hooks 之 useLayoutEffect

前言

在之前我们介绍过 useEffect hook ,今天介绍的 useLayoutEffect 其实大部分的功能跟 useEffect 一样,我可以将 side effect 放进这两 个 hook 做处理,但为什麽已经有了 useEffect 还要有个 useLayoutEffect 呢? 那些微的差距是什麽?今天就让我们来了解一下 useLayoutEffect 吧!

useLayoutEffect

首先,还是先介绍 useLayoutEffect 的基本使用方式,它跟 useEffect 一样接收两个参数:

  1. callback
  2. dependency array
useLayoutEffect(() => {
  // side effect
},[])

与 useEffect 最主要的差异:

  1. useLayoutEffect 的执行时间是在浏览器渲染画面之前。
    所以整个 flow 会是:
    1. 执行 Lazy initialize
    2. React render
    3. React 更新 DOM
    4. 执行 useLayoutEffect
    5. 浏览器渲染画面
    6. 执行 useEffect
  2. useLayoutEffect 是同步执行,所以一定会等到 useLayoutEffect 的 callback 执行完,浏览器才会渲染画面。

接下来就让我们来看看使用它的时机吧!

范例

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .container {
      position: relative;
    }

    .box {
      width: 100px;
      height: 100px;
      background: black;
      position: absolute;
    }
  </style>
</head>

<body>
  <div id='root'></div>
  <script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
  <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
  <script src="https://unpkg.com/@babel/[email protected]/babel.js"></script>

  <script type='text/babel'>
    const { useLayoutEffect, useEffect } = React
    function App() {
      const boxContainer = React.useRef(null)

      useEffect(() => {
        boxContainer.current.style.top = '200px'
      }, [])

      return (
        <div className='container'>
          <div className='box' ref={boxContainer}>
          </div>
        </div>
      )
    }

    ReactDOM.render(<App />, document.getElementById('root'))

  </script>
</body>

</html>

上面的范例,假设我们有一个 div 需要在 render 之後改变它的位置。在这边我们先使用了 useEffect 搭配 useRef ,去改变 box 的 style。如果你打开画面重新整理之後,会看到这样闪一下的情况。

这是因为 useEffect 的执行顺序是在浏览器渲染之後,所以一开始的 box在 top 0px 的位置会被渲染出来,之後因为执行 useEffect 才移动到设定的位置。这个时候就是 useLayoutEffect 的出场时机啦!

当我们将 useEffect 改成 useLayoutEffect ,这个问题就会改善了!
所以当我们某些时候要改变一些 DOM 元素的尺寸、大小和颜色,可以考虑使用 useLayoutEffect 去做。但大部分情况其实使用 useEffect 就可以了!

以上就是今天的分享,如果有任何问题都欢迎在下方留言!

该文章同步发布於:我的部落格


<<:  [Day26] 求值策略

>>:  [Day 26] - React 前端串後端 - 串接登入

进击的软件工程师之路-软件战斗营 第一周

学习进度 二维阵列与记忆体位置复习 物件导向 物件导向的三大特性(封装、继承、多型) 封装性的特色与...

Day 9 python函式

今天我们要介绍的是python的函式,所谓的函式就是指当我们需要做到重复的动作时可以使用函式来简化程...

[Day25] - Using Redux with Web Component

使用组件跟组件的组合 , 形成一个页面 势必会遇到经典的组件传值 issue (下图左侧) 以大家常...

JS 27 - 平滑滚动,让视窗不再是闪电侠!

大家好! 我们今天要实作让视窗能平滑地滚动到锚点。 我们进入今天的主题吧! 程序码 (functio...

[Lesson1] Android菜鸟的前言

大家好,小弟弟我在今年的时候,开始了Android 开发的学习,看到自己写的Code烧录到手机,能够...