zoukankan      html  css  js  c++  java
  • useEffect和useLayoutEffect执行时机

    流程

    1. react在diff之后,会进入commit阶段,将新生成的虚拟DOM发生的变化映射到真实DOM上
    2. 在commit的前期,会调度一些生命周期方法,对于类组件来说,会触发getSnapshotBeforeUpdate。对于函数组件来说,会调度useEffect。
    3. 但是并不是立即执行,在此阶段,会把useEffect入列到react维护的调度队列中,给一个普通的优先级,异步执行。
    4. 之后,在将新生成的虚拟DOM发生的变化映射到真实DOM上的过程中,会通过commitWalk根据不同的fiberNode进行DOM修改。
    5. 当commitWalk遇到类组件时,不会进行任何操作,因为没有真实的dom节点,直接return,处理下一个节点
    6. 但对于有了hooks的函数组件来说,会同步调用上一次渲染时useLayoutEffect函数的destroy方法
    7. 注意节点在commitWalk后,变化已经被映射到真实的DOM上了
    8. 但是由于JS线程和渲染线程是互斥的,真实的DOM虽然已经改变了,浏览器却没有立刻渲染到屏幕上
    9. 此时会同步执行对应的生命周期方法,如componentDidmount、componentDidUpdate以及useLayoutEffect的create方法。此时如果对DOM进行了操作,会一起处理
    10. 在react中,commit不会被打断,直至所有节点都commit结束,react更新完成,JS才停止执行
    11. 浏览器此时才会进入渲染线程,将发生变化的DOM渲染到屏幕上,因此react只用了一次回流、重绘的代价,将所有需要更新的DOM节点更新了
    12. 浏览器渲染完成后,react开始之前之前提到的调度队列,才开始执行useEffct产生的函数

    一些结论

    1. useEffect的create函数,调用时机和位置都与componentDidMount,componentDidUpdate 一致,且都是被 React 同步调用,都会阻塞浏览器渲染。

    2. 将对DOM的操作放在useLayoutEffect中,性能更好

  • 相关阅读:
    Git for Android Studio 学习笔记
    ACM-线段树区间更新+离散化
    hdu 1394 逆序数(线段树)
    Android瀑布流照片
    Android照片墙-多图加载
    Android-加载图片避免OOM
    Android-自定义View实现ImageView播放gif
    maven---工程建立及目录添加--
    oracle--视图(2)---
    Hibernate---Hql查询2---
  • 原文地址:https://www.cnblogs.com/ashen1999/p/14894741.html
Copyright © 2011-2022 走看看