当前位置: 首页 > news >正文

JSX本质是什么

JSX的本质

JSX (JavaScript XML) 是 JavaScript 的语法扩展,它的本质是:

  • 语法糖:JSX不是有效的JavaScript代码,最终会被编译为标准的JavaScript代码
  • 函数调用:JSX会被编译为React.createElement()函数调用(或类似函数)
  • 描述 UI 的结构:提供了一种声明式的方式描述用户界面

原始JSX代码:

const element = <h1 className="title">Hello, world!</h1>;

编译后的JavaScript代码

const element = React.createElement('h1',                      // 标签名{ className: 'title' },    // 属性对象'Hello, world!'            // 子元素
);

JSX转换为真实DOM的过程

1、编译阶段(Babel)处理

工具:Babel+@babel/preset-react
作用:将JSX转化为React.createElement调用

原代码:

<div className="container"><Button color="blue">Click</Button>
</div>

转化后代码:

React.createElement('div',{ className: 'container' },React.createElement(Button,{ color: 'blue' },'Click')
)

2、createElement() 调用会返回一个虚拟DOM节点

这是一个普通的JavaScript对象,描述DOM的真实样式
如下:

{type: 'div',props: {className: 'container',children: {type: Button,props: {color: 'blue',children: 'Click'}}}
}

3、渲染阶段(ReactDOM处理)

  • 首次渲染:ReactDOM.render()或根组件的render()
  • 更新渲染:状态或属性变化时

具体过程:

1、创建虚拟DOM树:React根据组件创建完整的虚拟DOM树
2、协调(Reconciliation)

  • 比较新旧DOM差异(Diff算法)
  • 找出需要更新的最小变化集
    3、提交(commit)
  • 将变化应用到真实DOM上
  • 执行生命周期方法(如 componentDidMount或useEffect)

具体DOM操作:

创建节点:document.createElement()
设置属性:element.setAttribute()
添加子节点:parent.appendChild()
更新节点:精细的 DOM 操作而非整体替换

为什么将变化应用到DOM树上之后 还要执行生命周期

1、当生命周期(如componentDidMount 、componentDidUpdate )或 useEffect 触发时,react保证:

  • DOM已实际更新完成:可以安全地执行依赖于 DOM 的操作(如测量元素尺寸、调用第三方库初始化等)
  • 避免“半成品”状态:如果先执行生命周期再更新 DOM,开发者可能会看到不一致的 UI 状态。
componentDidMount() {// 此时 div 已挂载到真实 DOM,可以正确获取宽度const width = this.divElement.clientWidth; 
}render() {return <div ref={el => this.divElement = el} />;
}

2、副作用执行的正确时机

React 将副作用(如数据获取、订阅)分为三个阶段:
1、render阶段:计算虚拟DOM差异(可中断,无副作用)
2、commit阶段:

  • Before Mutation:执行getSnapshotBeforeUpdate(获取 DOM 更新前的快照)
  • Mutation:将变更应用到真实DOM上
  • Layout:同步执行 componentDidMount/Update 和 useLayoutEffect(此时 DOM 已更新,但浏览器尚未绘制)
    3、Paint阶段:浏览器绘制后,异步执行useEffect

这种分离保证了:

  • 同步紧急操作(如 DOM 测量)在 useLayoutEffect 中立即执行。
  • 非紧急操作(如数据请求)在 useEffect 中异步执行,避免阻塞渲染。

3、与 Fiber 架构的协调机制配合
React Fiber 的调度机制需要:

  • 可中断的 Render 阶段:虚拟 DOM 计算可被打断,但必须保证提交到 DOM 的变更是一次性、不可中断的。
  • 批量更新优化:多个状态更新可能合并为一次 DOM 修改,生命周期在最终提交后统一触发
// React 的提交阶段伪代码
function commitRoot() {// 1. 应用 DOM 变更commitMutationEffects();// 2. 同步执行生命周期/布局 EffectcommitLayoutEffects(); // componentDidMount/Update, useLayoutEffect// 3. 标记任务完成,安排异步 EffectschedulePassiveEffects(); // useEffect
}

4、错误边界与回滚机制

如果在生命周期或 Effect 中抛出错误:

  • React 可以捕获错误并显示备用 UI(通过 Error Boundary)。
  • DOM 已处于一致状态,不会留下部分更新的界面。

总结:React 的生命周期/Effect 执行顺序设计

阶段执行内容特点
Before MutationgetSnapshotBeforeUpdate获取更新前 DOM 状态
Mutation应用 DOM 变更实际修改真实 DOM
LayoutcomponentDidMount/Update、useLayoutEffect同步执行,DOM 已更新
PaintuseEffect异步执行,浏览器已绘制

这种设计保证了:

  • 可靠性:DOM操作后生命周期操作安全访问DOM
  • 性能:将副作用分类处理,避免阻塞渲染
  • 一致性:确保UI和数据同步
http://www.dtcms.com/a/337873.html

相关文章:

  • AI行业应用深度报告:金融、医疗、教育、制造业落地案例
  • Docker之redis安装
  • linux中的hostpath卷、nfs卷以及静态持久卷的区别
  • 使用websockets中的一些问题和解决方法
  • 数据结构04(Java)-- ( 归并排序及其时间复杂度)
  • gflags框架安装与使用
  • 手机视频怎么提取音频?3步转成MP3,超简单!
  • Vue 中 v-for 的使用及 Vue2 与 Vue3 的区别
  • Vue 3中watch的返回值:解锁监听的隐藏技巧
  • Navicat 无法登录时找回 SQL 文件的方法
  • Tidio实时聊工具
  • Linux上安装PostgreSQL-源码编译安装备份恢复(超详细)
  • 视觉语言导航(4)——强化学习的三种方法 与 优化算法 2.43.4
  • IP白名单、网段白名单
  • Docker小游戏 | 使用Docker部署文字风格冒险网页小游戏
  • 如何选择一个好的软件成分分析工具?
  • 【计算机视觉与深度学习实战】05计算机视觉与深度学习在蚊子检测中的应用综述与假设
  • 【java中springboot引入geotool】
  • apisix负载均衡测试
  • 负载均衡终极指南:从流量分发到云原生架构的核心解析
  • Spring学习笔记:@Async Spring异步任务的深入学习与使用
  • 基于CentOS 7.6搭建GitLab服务器【玩转华为云】
  • TVS二极管选型指南
  • 构建高效智能语音代理:技术架构、实现细节与API服务推荐
  • 5G + AI + 云:电信技术重塑游戏生态与未来体验
  • Java基础的128陷阱
  • BAS16XV2T1G ON安森美半导体 高速开关二极管 电子元器件IC
  • 【本地部署问答软件Apache Answer】Answer开源平台搭建:cpolar内网穿透服务助力全球用户社区构建
  • JVM 垃圾回收基础原理:深入探索内存自动管理机制
  • 决策树学习报告