react运行原理(渲染机制)

39 阅读8分钟

1 组件 VS. 组件实例 VS. react元素 VS. DOM元素

组件函数是一个函数,组件实例是函数的具体应用,类似于类和实例对象,组件实例是独立的,拥有自己的生命周期,state,props,react执行代码时,运行组件实例时,会调用组件函数,背后会运行react.createElement(),最终返回一个react element,react element是一个JavaScript对象,包含所有的创建DOM元素时需要的信息,具体创建DOM的工作由react DOM完成,根据信息创建具体的DOM 元素,然后浏览器重新绘制页面,展示出来

总结:使用组件函数时,写一个组件实例,返回react element(是一个普通的JavaScript对象,包含所有的DOM信息),ReactDOM创建对应的DOM元素 结合图说明如下:

image.png

1.1 补充 :组件实例和组件元素的区别

组件实例是 ,组件元素react element是最终函数返回的结果, 运行后,经过完整的渲染流程后,,调用Tab()组件函数后,返回的结果是react element,但是也可以不经过完整的流程,直接写Tab()调用函数,返回react elemnt 结合图说明如下:

image.png

2 渲染机制

2.1 引入

刚才说了从组件函数-->组件实例-->react元素-->>DOM元素-->屏幕的大体过程,那具体是怎么从react element到屏幕的呢
答案是从触发渲染--> 渲染阶段--> 提交阶段--> 浏览器绘制 这里的渲染是指react的一个计算阶段,和DOM操作无关,和屏幕展示更没有关系

Pasted image 20250715115516.png Pasted image 20250716144106.png

2.2 触发渲染:

触发渲染分两种情况,一个是初始渲染,所有的组件都被渲染,一个是状态更新,导致再渲染 再渲染:从整体上来说,触发条件是,state状态更新,但是从单个组件来说,触发的条件是state,props,context更新,

2.3 渲染阶段

渲染阶段的目标是得到实际需要进行的插入、删除、更新的DOM操作list,因为react不负责DOM操作,具体操作由react DOM库执行,所以react需要将这些操作计算出来,传递给react DOM

具体的过程是: 分为两种情况:初次渲染和后续state更新触发的渲染

  1. 初次渲染:调用所有的组件函数-->生成一个完整的react element tree-->构建一个完整的fiber tree-->(后面:react DOM创建所有的DOM元素-->屏幕绘制页面)

  2. state更新触发再渲染 当页面上进行某些操作,导致了状态更新时,为了尽可能的减少DOM的操作,因为DOM的操作是昂贵的,所以我们会先需要计算出有哪些元素是可以复用的,哪些需要更新属性,哪些需要删除和新增元素,所以react需要计算出具体需要进行的DOM操作--一个Effect list链表,

    【state更新触发渲染】 ----> 【调用对应的组件函数,生成一个新的局部react element tree】 ----> 【拼到完整的react element tree中(新的完整的react element tree)】 ------> 【根据这个新的react element tree和当前的fiber tree进行差分Diffing和协调Reconciliation :会深度遍历fiber tree,对每一个fiber比较这个fiber和react element tree判断是否需要复用fiber,是否需要更新、复用、删除、新增fiber,并将信息标记到fiber上】 ----> 【遍历完成之后会生成一个完整的workInProgress tree,也得到了一个effect list(需要操作的链表)】 这就是渲染阶段,在提交阶段react DOM会根据这个链表进行Dom操作最后屏幕重新绘制 需要说明的是:状态更新是批量提交,批量更新的,所以多个状态更新,最终会一次性生成一个新的react element tree, 协调过程是异步可中断的,被拆分为Fiber工作单元,支持优先级调度、暂停、丢弃和恢复

Pasted image 20250721101342.png ## 2.4 提交阶段

由react DOM、react Native或者其他的渲染器完成,根据Effect list链表信息,新增、删除、更新DOM,这个步骤是同步的,一次性更新,不可中断,避免只显示局部结果,保证UI和state是同步的

提交阶段完成后,WorkInProgress tree会成为新的Current Fiber tree


补充:Diffing差分原理

根据type和key来进行区分两个react element是否相同,是否需要删除和新增的,类型相同并且key一样,视为同一个元素,否则视为不同元素,没有key时,仅比较相同位置的type相同时,视为同一元素,否则视为不同元素,确认相同元素后再确认是否需要更新props,确认更新元素还是直接复用,在Fiber上标记为不同的Tag:新增,删除,更新,复用

-key:元素的key属性让react去用于区分不同的组件实例 渲染时
1. 如果Key保持一致--> 元素也会保持在DOM中,用于在列表中使用keys 2. 如果改变key-->DOM元素会被销毁和重建,用于重置状态

背后的原理: 差分核心规则:比较type和key,两者都相同为同一元素,没有key时,仅比较相同位置的type相同时,视为同一元素,否则视为不同元素

key作用:元素的key属性让react去用于区分不同的组件实例,告诉差分算法该元素的唯一性--标识

  1. 如果Key保持一致--> 元素也会保持在DOM中,在列表中使用key(稳定key):无key:一次新增,两次更新,有key:一次新增
  2. 如果改变key-->DOM元素会被销毁和重建,用于重置状态 image.png
Pasted image 20250721133641.png ---

3 渲染逻辑规则:纯组件

3.1 什么是渲染逻辑?

react组件的两种逻辑:渲染逻辑render logic+处理逻辑handler logic

  1. 渲染逻辑:描述组件的视图结构,就是页面怎么展示,位于组件函数顶层代码中,每次渲染时都会执行
  2. 处理逻辑:事件处理函数触发时执行,或者是useEffect对应情况时执行,实际代码在事件处理函数或useEffect中,:更新state,发起http请求,读取输入字段,导航到另一个页面

3.2 概念:纯函数和副作用

  • 纯函数:不与外界交互的函数,相同输入相同输出,无副作用
  • 副作用:函数依赖或修改了作用域外的数据,对外界造成了影响,包括:修改外部变量,http请求,操作DOM,依赖可变数据(Math.random(),new Date()),提醒:副作用不是有害的,只是需要隔离到可控范围,毕竟如果程序需要与外界交互才能产生实际意义

渲染逻辑原则:与纯函数类似,pure,相同输入相同输出(相同JSX),不能有副作用:

  1. 网络请求
  2. 启动定时器
  3. 直接操作DOM
  4. 修改外部变量或者是对象
  5. 更新状态或refs-->会导致无限循环

3.3 批量更新状态,更新--渲染是异步的

更新状态特点:批量更新,异步更新 Pasted image 20250721153957.png

强制同步书信 reactDom.flushSync() 除了状态更新是批处理的,react 18后,自动批处理 事件处理,timeouts,promise,nativeEvents Pasted image 20250721154335.png

4 react合成事件--事件传播和事件委托

react中所有的事件都被委托到root DOM container上

Pasted image 20250721160942.png

在事件处理器中使用事件,使我们获得的是一个合成事件对象,不是浏览器原生的对象-->在不同浏览器上事件一样工作。区别是绝大多数的合成事件对象会冒泡,包括不会在原生浏览器上冒泡的事件,比如focus blurchange,只有scoll事件不会冒泡

合成事件 SyntheticEvent: 对DOM原生事件对象的封装

  • 拥有和原生事件对象相同的方法比如e.stopPropagation() e.preventDefault()
  • 修复浏览器的差异,让事件在不同的浏览器中一样运行
  • 绝大多数事件冒泡(包括focus blur change 除了scoll)

react VS. JS 中事件处理器:

  • 阻止默认行为:必须显式调用 e.preventDefault()(返回 false 无效)
  • 事件命名:始终使用驼峰式(如 onMouseEnter
  • 事件阶段:通过 onClickCapture 在捕获阶段处理事件

5 框架 VS. 库: react是一个库而不是框架

famework:

  • 轻松自如:构建完整应用所需的一切在框架中
  • 别无选择:你只能使用框架的工具和约定(这并不总是坏的) library:
  • 自由:你可以(需要)选择不同的第三方的库来构建完整的应用
  • 决策疲劳:你需要研究、下载、学习并随时更新多个外部库 react 第三方生态:
Pasted image 20250721163341.png

react之上的框架:NEXT.js Remix Gatsby React 框架还提供了许多其他功能:服务器端渲染(SSR)、静态网站生成(SSG)、更好的开发体验(DX)等

Pasted image 20250721164019.png