概述
- React创立的应用程序分两局部,一部分是首次创立的Mount阶段,另一部分是常见的更新更新和事件触发阶段Update阶段。
- 对于DOM更新是两套流程,首次创立和DOM更新。
- 简述React中Class组件生命周期的运行工夫点和HOOK组件中UseEffect、UseLayout的运行工夫点
Render阶段
- Render阶段又分beginWork阶段和complete阶段
- Render阶段次要的目标是为每一个HTML节点生成Fibre节点,须要执行的事件也会挂载到Fibre节点上, 并依据页面构造生成Fibre链表
Render阶段生成Fibre链表完结后,交给commit阶段。commit阶段会在此基础上执行事件、渲染或更新DOM,最初绘制到页面上。
beginWork阶段——创立Fibre节点
- 在这个阶段会更依据页面的HTML构造和HTML元素生成创立对应的Fibre对象,记录节点的相干信息。如节点类型、节点上的属性、父级对象...
- 在产生页面更新时,React会为每个元素从新构建一个新的Fibre对象。会在此阶段尝试复用上次的Fibre对象,如果没有产生扭转就间接复制过去。
会在此阶段调用shouldComponentUpdate生命周期函数,若调用该函数,则react页面在视觉上不会产生更新,但ref的援用还是会产生更新。
complete阶段——创立虚构DOM
- beginWork生成Fibre对象后,在Complete办法中生成虚构DOM。如果该Fibre节点有父级对象,则会将创立的虚构DOM挂载到父级Fibre的属性中
当执行到最初一个节点时,会失去一个虚构DOM树,而后进入Commit阶段。
Fibre对象和虚构DOM的构建
Commit阶段
- React相干生命周期
- 解决Render阶段的Fibre链表,执行事件或更新DOM。
commit阶段分3局部,beforeMuation、Mutation、Layout。
beforeMutaion阶段
- 解决focus事件
- 对于Class组件而言,解决getDerivedStateFromProps生命周期函数,能够管制本次更新过程中,页面能不能产生扭转。
- 对于HOOK而言,会将useEffect中的回调函数退出一个队列,会在整个Commit阶段实现当前再异步执行,而在本阶段并不会间接执行。
- 调用Class组件的getSnapshotBeforeUpdate生命周期函数
Mutation阶段
- Mutation阶段会遍历蕴含useEffecTarget属性t的Fibre链表,有须要文本更新的就更新,有须要更新ref的就更新ref。
- 对DOM节点进行增删改查的操作。处理结果会反馈到Fibre节点中(如新增fibre节点,删除fiebr节点),这个Fibre节点并不一定是以后Fibre节点,也可能是以后Fibre节点的父级。
- 对于以后Fibre节点产生更新的状况,若是HOOK组件,会调用useLayoutEffect的销毁函数;对于Class组件而言,会调用componentDidWillUnMount生命周期函数。如果以后Fibre节点类型不是HOOK或Class类型,如div类型、span类型...就不会执行销毁函数的回调。(PS:更新后的后果必须保障上一次的销毁函数调用)
- Mutation阶段的current指针还是之前的,所以执行销毁函数的回调没有问题。
layout阶段
- layout阶段会替换current指针,这就是双缓存机制产生变更的工夫点。
- layout阶段会依据current指针是否有值,执行不同的生命周期函数。没有值,执行Class组件的componentDidMount生命周期;有值就执行componentDidUpdate生命周期函数。
- 对于HOOK而言,会调用useEffect的回调函数,将销毁函数退出到队列中。本阶段的最初会查看这个队列,如果有的话会执行队列工作,直到清空后才算实现layout阶段。
- this.setState()的回掉函数,也就是第二个参数,也是在这个阶段执行。
- 会执行useLayoutEffect的回调函数,并将新的销毁函数增加到一个队列中。再次更新时,Mutation阶段就会执行UseLayout的销毁函数。