:::info useLayoutEffect看起来和useEffect非常的相似,事实上他们也只有一点区别而已。

  • useEffect会在渲染的内容更新到DOM上之后执行,不会阻塞DOM的更新。
  • useLayoutEffect会在渲染的内容更新到DOM上之前执行,会阻塞DOM的更新。

如果我们希望在某些操作发生之后再更新DOM,那么应该将这个操作放到useLayoutEffect这个hook中。

  • 相当于vue中的this.$nextTick()函数的使用,在下一次dom更新之前进行调用。 :::

    1、案例演示

    1、执行的原理问题:我们设置的初始化状态为100,我们的组件进行相应的挂载,执行useEffect hook函数,不满足条件,页面成功的渲染,界面的值为最初的状态10。我们的useEffect hook是对count数据进行了相应的依赖,如果我们的count数据一旦发生变化,那么我们的useEffect函数将会直接执行。 2、界面成功的渲染后,我们对按钮进行点击,将count的值设置为了0,此时我们的页面count应该先显示为0,但是我们的useEffect hook fuction对count状态进行了依赖,count发生了变化,此时的useEffect hook将会执行,进行相应的判断,判断的条件成立,设置了新的count的值,界面也会进行更新。此时count发生了变化useEffect将会再次执行条件不成立。这个函数停止运行。 3、需要解决页面闪烁的问题。

  1. import React, { useState, useEffect } from 'react'
  2. export default function EffectHookDemo() {
  3. // 定义状态和修改状态的行为
  4. const [count, setCount] = useState(10)
  5. // 使用useEffect在组件挂载完毕后执行的hook函数
  6. useEffect(() => {
  7. # 最开始执行了一次,按钮点击之后再执行两次 里面的逻辑原理很重要
  8. // 执行相应的逻辑问题
  9. if(count === 0) {
  10. setCount(Math.random())
  11. }
  12. }, [count])
  13. return (
  14. <div>
  15. <h2>useEffect来修改count的变化</h2>
  16. <h1>{ count }</h1>
  17. <button onClick={ () => setCount(0)}>修改count</button>
  18. </div>
  19. )
  20. }

为了解决上述页面会进行两次的渲染(虽然渲染的时间很短)的问题,我们可以使用useLayoutEffect Hook对上述的代码进行相应的改造,解决页面闪烁的问题。

2、useLayoutEffect的使用

  1. // useLayoutEffect页面DOM更新之前执行 就是需要将操作状态的行为执行完毕后再渲染DOM,简单的理解就是阻塞DOM的渲染。
  2. import React, { useState, useLayoutEffect } from 'react'
  3. export default function EffectHookDemo() {
  4. // 定义状态和修改状态的行为
  5. const [count, setCount] = useState(10)
  6. // 使用useEffect在组件挂载完毕后执行的hook函数
  7. // useEffect(() => {
  8. // if(count === 0) {
  9. // setCount(Math.random())
  10. // }
  11. // }, [count])
  12. // 使用useLayoutEffect hook解决上述的问题 解决页面闪烁的问题
  13. useLayoutEffect(() => {
  14. if(count === 0) {
  15. // 修改状态
  16. setCount(Math.random())
  17. }
  18. }, [count])
  19. return (
  20. <div>
  21. <h2>useEffect来修改count的变化</h2>
  22. <h1>{ count }</h1>
  23. <button onClick={ () => setCount(0)}>修改count</button>
  24. </div>
  25. )
  26. }

3、原理解析

:::info useLayoutEffect hook的原理解析:
useLayoutEffect看起来和useEffect非常的相似,事实上他们只有一点区别而已:

  • useEffect会这渲染的内容更新到DOM上执行,不会阻塞DOM的更新
  • useLayoutEffect会再渲染的内容更新到DOM上之前执行,会阻塞DOM的更新

如果我们希望某些操作发生之后再更新DOM,那么可以将这个操作放到useLayoutEffect操作中 :::