• React中useLayoutEffect和useEffect的区别


    重点: 1.二者函数签名相同,调用方式是一致的

       2. 怎么简单进行选择: 无脑选择useEffect,除非运行效果和你预期的不一致再试试useLayoutEffect

    区别详解:
    useEffect是异步执行,而且是在渲染被绘制到屏幕之后执行。
    流程如下:
    你以某种方式触发了rerender(改变state,或者父组件发生rerender)
    React渲染你的组件(调用组件函数)
    屏幕在视觉上更新(真实dom操作)
    然后useEffect运行

    useLayoutEffect是同步执行,时机在渲染之后但在屏幕更新之前。

    流程如下:
    你以某种方式触发了rerender(改变state,或者父组件发生rerender)
    React渲染你的组件(调用组件函数)
    useLayoutEffect运行,React等待它完成
    屏幕在视觉上更新(真实dom操作)

    代码实战

    const BlinkyRender = () => {
      const [value, setValue] = useState(0);
    
      useLayoutEffect(() => {
        if (value === 0) {
          setValue(10 + Math.random() * 200);
        }
      }, [value]);
    
      console.log('render', value);
    
      return (
        <div onClick={() => setValue(0)}>
          value: {value}
        </div>
      );
    };
    


    当点击div时,状态立即改变(value重置为0),这将重新Render组件,然后运行Effect——将值设置为某个随机数,并再次重新Render。


    也就是是两次Rerender会快速连续发生。分别换用useLayoutEffect和useEffect观察有什么不同。

    你会发现useLayoutEffect的版本会在组件render两次的情况下仅在视觉上更新一次。而useEffect版本在视觉上也会呈现两次,所以会看到闪烁,从0闪烁变成对应的随机数。

    所以到底什么时候使用useLayoutEffect呢?

    如果你的组件在状态更新时闪烁,比如它首先以部分就绪状态呈现,然后立即以最终状态重新呈现——这是一个很好的线索,是时候换useLayoutEffect了。

    当您的更新是两步(或多步)过程时,就会出现这种情况。你想在重新绘制屏幕之前一起批处理多个更新吗,试试useLayoutEffect。

    在大多数情况下,你的effect函数会在对应的依赖项如state或props改变时执行,而对应的回调逻辑往往不会立即影响或根本不影响页面视觉。
    比如发一个ajax请求
    或者你设置一个了事件处理器


    大多数时候,使用useEffect是正确的。如果您的代码导致闪烁,切换到useLayoutEffect,看看是否有帮助。


    因为useLayoutEffect是同步的,也就是阻塞的,在你的effect运行完之前,视觉不会更新。如果你的effect中有计算密集型代码,它可能会导致性能体验问题,比如卡顿。大多数effect在运行时并不需要"stop the world",普通的 useEffect几乎可以满足我们所有的需求。

  • 相关阅读:
    Ural 1996 Cipher Message 3 (生成函数+FFT)
    UVA 12633 Super Rooks on Chessboard (生成函数+FFT)
    HDU 5307 He is Flying (生成函数+FFT)
    BZOJ 2039 人员雇佣 (最小割)
    BZOJ 3158 千钧一发 (最大流->二分图带权最大独立集)
    BZOJ 3144 [HNOI2013]切糕 (最大流+巧妙的建图)
    BZOJ 3774 最优选择 (最小割+二分图)
    BZOJ 3876 [AHOI/JSOI2014]支线剧情 (最小费用可行流)
    BZOJ 3771 Triple (FFT+生成函数+容斥)
    洛谷 P3121 【[USACO15FEB]审查(黄金)Censoring (Gold)】
  • 原文地址:https://www.cnblogs.com/flamestudio/p/13927413.html
Copyright © 2020-2023  润新知