React(二):JSX语法解析+综合案例
事件绑定
this绑定方式
问题:在事件执行后,需获取当前类的对象中相关属性,此时需要this——当打印时,发现this为undefined,这又是为啥?
假设有一个btnClick函数,但它并不是我们主动调用的,而是当button发生改变时,React内部调用→内部调用时,并不知道要如何绑定正确的this
解决办法:
- bind给btnClick显示绑定this
- 使用 ES6 class fields 语法
- 事件监听时传入箭头函数(较为推荐)
<body><div id="root"></div><script src="../lib/react.js"></script><script src="../lib/react-dom.js"></script><script src="../lib/babel.js"></script><script type="text/babel">/* this的四种绑定规则 1.默认绑定:独立执行foo()2.隐式绑定:被一个对象执行obj.foo() ->obj3.显示绑定:call/apply/bind foo.call('aaa') ->String('aaa')4.new绑定:new Foo() -> 创建一个新对象,并赋值给this*///1.创建rootconst root = ReactDOM.createRoot(document.getElementById('root'))//2..定义App根组件class App extends React.Component {constructor() {super()this.state = {count:100}}btn1Click() {this.setState({ count:this.state.count+1})}// 箭头函数无this,只能去上一层找btn2Click = () => {this.setState({ count:this.state.count-1})}btn3Click() {this.setState({ count:this.state.count-1})}render(){const {count} = this.statereturn (<div><h1>{ count }</h1>{/* 1.this绑定方式一:bind绑定 */}<button onClick={this.btn1Click.bind(this)}>按钮1</button>{/* 2.this绑定方式二:箭头函数ES6 class fields */}<button onClick={this.btn2Click}>按钮2</button>{/* 3.this绑定方式三:直接传入一个箭头函数 */}<button onClick={() => this.btn3Click()}>按钮3</button></div>)}}// 3.将App组件渲染到root上root.render(<App />)</script>
</body>
事件参数传递
1.获取默认参数:即event对象
2.获取更多参数:可通过传入一个箭头函数,主动执行的事件函数,并且传入相关的其他参数
<body><div id="root"></div><script src="../lib/react.js"></script><script src="../lib/react-dom.js"></script><script src="../lib/babel.js"></script><script type="text/babel">//1.创建rootconst root = ReactDOM.createRoot(document.getElementById('root'))//2..定义App根组件class App extends React.Component {constructor() {super()this.state = {message:"Hello World"}}btnClick (event,name,age) {console.log("点击事件", event,this);console.log("name:", name, "age:",age);}render(){const {message} = this.statereturn (<div>{/* 1.event参数的传递 */}<button onClick={this.btnClick}>按钮1</button><button onClick={(event) => this.btnClick(event)}>按钮2</button>{/* 2.传递额外的参数 */}<button onClick={(event) => this.btnClick(event, "why", 30)}>按钮3</button></div>)}}// 3.将App组件渲染到root上root.render(<App />)</script>
</body>
条件渲染
在vue中,我们会通过指令来控制:比如v-if、v-show;
在React中,所有的条件判断都和普通的JavaScript代码一致;
常见条件渲染方式:
1.条件判断语句
2.三元运算符
3.与运算符&&
<body><div id="root"></div><script src="../lib/react.js"></script><script src="../lib/react-dom.js"></script><script src="../lib/babel.js"></script><script type="text/babel">//1.创建rootconst root = ReactDOM.createRoot(document.getElementById('root'))//2..定义App根组件class App extends React.Component {constructor() {super()this.state = {isReady:true,friend:{name:"lucy",age:22,gender:"女"}}}render(){const {isReady,friend} = this.state// 1.条件判断方式一:使用if进行条件判断let showElement = nullif(isReady) {showElement = <h2>准备开始比赛吧</h2>}else{showElement = <h1>我还没有准备好嘞</h1>}return (<div>{/* 方式一:根据条件给变量赋值不同的内容 */}<div>{ showElement }</div>{/* 方式二:三元运算符 */}<div>{isReady? <button>准备开始</button> : <button>还没有准备好</button> }</div>{/* 方式三:&&运算符 */}{/* 场景:当某一个值,有可能为undefined时,使用&&进行条件判断 */}<div>{ friend && <div>{friend.name + friend.age + friend.gender}</div> }</div></div>)}}// 3.将App组件渲染到root上root.render(<App />)</script>
</body>
实现v-show的效果:
class App extends React.Component {constructor() {super()this.state = {message:"Hello World",isShow:true}}ediClick() {this.setState({isShow:!this.state.isShow})}render(){const {message,isShow} = this.statereturn (<div><button onClick={this.ediClick.bind(this)}>切换1</button><h1 >{ isShow? message : "" }</h1>{/* v-show的效果 */}<button onClick={this.ediClick.bind(this)}>切换2</button><h1 style={{display:isShow ? "block" : "none"}}>{ message }</h1></div>)}
}
列表渲染
class App extends React.Component {constructor() {super()this.state = {students:[{id:1, name:'Jack', age:18},{id:2, name:'Tom', age:20},{id:3, name:'Lucy', age:22},{id:4, name:'Lily', age:24}]}}render(){const {students} = this.state// 展示年龄大于20的const filterStudents = students.filter(item => item.age >= 20)return (<div><h2>学生信息列表</h2><div className="list">{/* 绑定唯一标识key:提高diff算法时的效率 */}{filterStudents.map(item => <div key={item.id} className="item"><p>id:{item.id}</p><p>姓名:{item.name}</p><p>年龄:{item.age}</p></div>)}</div></div>)}
}
原理本质
babel转换
实际上,jsx 仅仅只是 React.createElement(component, props, ...children) 函数的语法糖→所有的jsx最终都会被转换成React.createElement的函数调用
createElement需要传递三个参数:
1.参数一:type
- 当前ReactElement的类型;
- 如果是标签元素,那么就使用字符串表示 “div”;
- 如果是组件元素,那么就直接使用组件的名称;
2.参数二:config
- 所有jsx中的属性都在config中以对象的属性和值的形式存储;
- 比如传入className作为元素的class;
3.参数三:children
- 存放在标签中的内容,以children数组的方式进行存储;
直接编写jsx代码:
<div><div className="header">header</div><div className="Content"><div>Banner</div><ul><li>数据列表1</li><li>数据列表2</li><li>数据列表3</li></ul></div><div className="footer">footer</div>
</div>
经过babel转译后:
React.createElement(
'div',
null,
React.createElement('div', { className: 'header' }, 'header'),
React.createElement('div',{ className: 'Content' },React.createElement('div', null, 'Banner'),React.createElement('ul',null,React.createElement('li', null, '数据列表1'),React.createElement('li', null, '数据列表2'),React.createElement('li', null, '数据列表3'))
),
React.createElement('div', { className: 'footer' }, 'footer')
);
虚拟DOM生成
通过React.createElement最终创建出一个ReactElement对象→它组成了一个JS对象树→即虚拟DOM

阶段案例-购物车

<body><div id="root"></div><script src="../lib/react.js"></script><script src="../lib/react-dom.js"></script><script src="../lib/babel.js"></script><script src="./data.js"></script><script src="./format.js"></script><script type="text/babel">// 1.定义App根组件class App extends React.Component {constructor() {super()this.state = {books: books}}getTotalPrice() {const totalPrice = this.state.books.reduce((preValue, item) => {return preValue + item.count * item.price}, 0)return totalPrice}changeCount(index, count) {const newBooks = [...this.state.books]newBooks[index].count += countthis.setState({ books: newBooks })}removeItem(index) {const newBooks = [...this.state.books]newBooks.splice(index, 1)this.setState({ books: newBooks })}renderBookList() {const { books } = this.statereturn <div><table><thead><tr><th>序号</th><th>书籍名称</th><th>出版日期</th><th>价格</th><th>购买数量</th><th>操作</th></tr></thead><tbody>{books.map((item, index) => {return (<tr key={item.id}><td>{index + 1}</td><td>{item.name}</td><td>{item.date}</td><td>{formatPrice(item.price)}</td><td><button disabled={item.count <= 1}onClick={() => this.changeCount(index, -1)}>-</button>{item.count}<button onClick={() => this.changeCount(index, 1)}>+</button></td><td><button onClick={() => this.removeItem(index)}>删除</button></td></tr>)})}</tbody></table><h2>总价格: {formatPrice(this.getTotalPrice())}</h2></div>}renderBookEmpty() {return <div><h2>购物车为空, 请添加书籍~</h2></div>}render() {const { books } = this.statereturn books.length ? this.renderBookList(): this.renderBookEmpty()}}// 2.创建root并且渲染App组件const root = ReactDOM.createRoot(document.querySelector("#root"))root.render(<App/>)</script></body>
format.js(数值格式化文件)
function formatPrice(price) {return "¥" + Number(price).toFixed(2)
}
data.js(数据文件)
const books = [{id: 1,name: '《算法导论》',date: '2006-9',price: 85.00,count: 1},{id: 2,name: '《UNIX编程艺术》',date: '2006-2',price: 59.00,count: 1},{id: 3,name: '《编程珠玑》',date: '2008-10',price: 39.00,count: 1},{id: 4,name: '《代码大全》',date: '2006-3',price: 128.00,count: 1},
]相关文章:
React(二):JSX语法解析+综合案例
事件绑定 this绑定方式 问题:在事件执行后,需获取当前类的对象中相关属性,此时需要this——当打印时,发现this为undefined,这又是为啥? 假设有一个btnClick函数,但它并不是我们主动调用的,而是…...
Gitee重新远程连接仓库(Linux)
Gitee重新远程连接仓库(Linux) 因为虚拟机重新安装了一回,所以需要重新和远程仓库连接,在网上找了很久没有找到相关操作,自己实操成功,记录下本博客,帮助有需要的人 确保新虚拟机安装Git 在新虚…...
Vitis HLS中的Array Partition与Array Reshape详解
Vitis HLS中的Array Partition与Array Reshape详解 引言 在高层次综合(HLS)设计中,数组是最常用的数据结构之一,但默认情况下,HLS会将数组映射到单个BRAM块,这会限制并行访问能力,成为性能瓶颈。为了克服这一限制&am…...
Centos离线安装openssl
文章目录 Centos离线安装openssl1. openssl是什么?2. openssl下载地址3. openssl-devel安装4. 安装结果验证5. 版本查看 Centos离线安装openssl 1. openssl是什么? OpenSSL 是一个开源的、跨平台的 加密工具库 和 命令行工具集,广泛用于实现…...
protobuf安装
安装 github官方链接 https://github.com/protocolbuffers/protobuf/ 以protobuf21为例 https://github.com/protocolbuffers/protobuf/releases/download/v21.11/protobuf-all-21.11.zip windows 解压好文件夹后,使用cmake,vs,qt creator等工具打开该项目,进行编译,编译需…...
《基于超高频RFID的图书馆管理系统的设计与实现》开题报告
一、研究背景与意义 1.研究背景 随着信息化时代的到来,运用计算机科学技术实现图书馆的管理工作已成为优势。更加科学地管理图书馆会大大提高工作效率。我国的图书管理体系发展经历了三个阶段:传统图书管理模式、现代图书管理模式以及基于无线射频识别&…...
小程序渲染之谜:如何解决“加载中...”不消失的 Bug(glass-easel)
🎉 小程序渲染之谜:如何解决“加载中…”不消失的 Bug 🎉 引言 在小程序开发中,渲染问题总能让人抓狂。😫 这次,我遇到了一个奇怪的 bug:产品详情页的内容已经正常显示,但页面却一…...
在 React 中使用 Web Components 的实践操作
前言 在现代前端开发中,React 和 Web Components 都是广泛使用且备受欢迎的技术。React 是一个用于构建用户界面的 JavaScript 库,提供了组件化的开发方式和高效的状态管理,而 Web Components 是一套原生的浏览器技术标准,允许开…...
网络原理之HTTPS(如果想知道网络原理中有关HTTPS的知识,那么只看这一篇就足够了!)
前言:随着互联网安全问题日益严重,HTTPS已成为保障数据传输安全的标准协议,通过加密技术和身份验证,HTTPS有效防止数据窃取、篡改和中间人攻击,确保通信双方的安全和信任。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要…...
五子棋小游戏-简单开发版
一、需求分析 开发一个基于 Pygame 库的五子棋小游戏,允许两名玩家在棋盘上轮流落子,当有一方达成五子连珠时游戏结束,显示获胜信息,并提供退出游戏和重新开始游戏的操作选项。 1.棋盘显示 : 显示一个 15x15 的五子棋…...
node-sass替换成Dart-sass(全是坑)
改了好久,人都改傻了,我是用的node:14.21.3,vue:2.5.2,webpack": "^3.12.0" 还好最后成功了,不然还准备要升级webpack版本试试,但/deep/换成::v-deep,人要死…...
2025中国科技大学少年班/创新试点班·初试备考测试卷(数学)
本卷考查内容:高中课程内容及拓展。 本卷考查形式:书面作答(客观题18小题解答题4题)。 卷首语:中科大少年班、创新班每年大规模招录在数理成绩优异的中学学生。其中初试数学题在高考基础上略有拓展,难度又低…...
即时通讯平台测试报告
1.项目概述 项目名称:即时通讯平台 版本号:V1.0.0 测试周期:2025年2月25日--2025年3月15日 测试目标:验证核心功能(登录、注册、消息收发、用户管理、群组功能等)的稳定性和性能指标。 2. 测试范围 功…...
如何记录Matlab程序运行过程中所占用的最大内存
有些时候,我们需要分析Matlab程序运行过程中所占用的最大内存。如果只是得到程序运行到当前位置所占用的内存,可以简单在程序当前位置插入memory命令即可: user memory; MemUsed_now user.MemUsedMATLAB; 但如果我们想要的是整个程序在运行…...
WIN11开发环境变量记录
这里写自定义目录标题 总图JAVA环境变量配置GIT环境变量配置NODEJS环境变量配置 总图 JAVA环境变量配置 新建系统变量。变量名:JAVA_HOME,变量值(可以选择浏览目录,JAVA的根目录,本处为D:\Java\jdk1.8.0_251ÿ…...
易语言模拟真人鼠标轨迹算法
一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序,它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言,原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势: 模拟…...
洛谷P9950 [USACO20FEB] Mad Scientist B
P9950 [USACO20FEB] Mad Scientist B - 洛谷 代码区: #include <iostream> #include <string>using namespace std; int main() {int n;cin>> n;string a;string b;cin >> a >> b;int flag,step0,i,t;for ( i 0; i < a.length(…...
【人工智能基础2】Tramsformer架构、自然语言处理基础、计算机视觉总结
文章目录 七、Transformer架构1. 替代LSTM的原因2. Transformer架构:编码器 - 解码器架构3. Transformer架构原理 八、自然语言处理基础1. 语言模型基本概念2. 向量语义3. 预训练语言模型的基本原理与方法4. DeepSeek基本原理 九、计算机视觉 七、Transformer架构 …...
prometheus自定义监控(pushgateway和blackbox)和远端存储VictoriaMetrics
1 pushgateway采集 1.1 自定义采集键值 如果自定义采集需求时,就可以通过写脚本 定时任务定期发送数据到 pushgateway 达到自定义监控 1.部署 pushgateway,以 10.0.0.42 节点为例 1.下载组件 wget https://github.com/prometheus/pushgateway/relea…...
设计模式之组合模式:原理、实现与应用
引言 组合模式(Composite Pattern)是一种结构型设计模式,它允许你将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得客户端可以统一对待单个对象和组合对象,从而简化了客户端代码。本文将深入探讨组合模式的原理…...
数字化转型 - 数据驱动
数字化转型 一、 数据驱动1.1 监控1.2 分析1.3 挖掘1.4 赋能 二、数据驱动案例2.1 能源工业互联网:绿色节能的数字化路径2.2 光伏产业的数字化升级2.3 数据中心的绿色转型2.4云迁移的质效优化2.5 企业数字化运营的实践2.6数字化转型的最佳实践 一、 数据驱动 从数…...
C++相关基础概念之入门讲解(上)
1. 命名空间 C中的命名空间(namespace)是用来避免命名冲突问题的一种机制。通过将类、函数、变量等封装在命名空间中,可以避免不同部分的代码中出现相同名称的冲突。在C中,可以使用namespace关键字来定义命名空间。 然后我们在调…...
【数学建模】层次分析法(AHP)详解及其应用
层次分析法(AHP)详解及其应用 引言 在现实生活和工作中,我们经常面临复杂的决策问题,这些问题通常涉及多个评价准则,且各准则之间可能存在相互影响。如何在这些复杂因素中做出合理的决策?层次分析法(Analytic Hierarchy Process…...
【大模型】Transformer、GPT1、GPT2、GPT3、BERT 的论文解析
前言 在自然语言处理(NLP)和深度学习的快速发展中,Transformer模型和 GPT系列模型扮演了至关重要的角色。本篇博客旨在对这些开创性的论文进行介绍,涵盖它们的提出时间、网络结构等关键信息,能够快速的理解这些模型的设…...
TCP怎么保证可靠传输
一:连接管理 TCP是面向连接的协议,在数据传输前必须通过三次握手建立连接,结束时必须四次挥手来终止连接。这确保双方都准备好通信。 二:序列号和确认应答 每个字节的数据都被分配了一个序列号,这允许接收方将受到的数…...
TimeGAN:开启时间序列生成新纪元,结合GAN与自回归模型的优势
今天周末,给大家介绍一篇时序数据生成网络TimeGAN,一种用于时间序列生成的新框架,它将无监督GAN方法的多功能性与有监督自回归模型对条件时间动态的控制相结合。通过利用有监督损失和联合训练的嵌入网络,TimeGAN在生成逼真的时间序…...
【Java 优选算法】分治-归并排序
欢迎关注个人主页:逸狼 创造不易,可以点点赞吗~ 如有错误,欢迎指出~ 数组分块如二叉树的前序遍历, 而归并排序就如二叉树的后序遍历 912. 排序数组 解法 使用归并算法 根据中间点划分区间, mid (right left ) / 2将左右区间排序合并两个有…...
【Kubernetes】Service 的类型有哪些?ClusterIP、NodePort 和 LoadBalancer 的区别?
在 Kubernetes 中,Service 是一种抽象的方式,用于将一组 Pod 进行连接并暴露给外部或集群内部访问。它的主要目的是通过提供稳定的 IP 地址和端口来允许其他服务或客户端与一组 Pod 进行通信。 Service 类型 Kubernetes 中 Service 有四种主要类型&…...
三格电子Modbus TCP转CANOpen网关相关问答
型号:SG-TCP-COE-210 Q1: Modbus TCP转CANOpen网关的主要功能是什么? A1: 该网关的核心功能是实现 Modbus TCP协议与CANOpen协议之间的双向数据转换,使支持Modbus TCP的工业设备(如PLC、HMI)能够与基于CANOpen协议的设…...
BSP、设备树和HAL的关系:以Xilinx Zynq为例与PC BIOS的对比
BSP、设备树和HAL的关系:以Xilinx Zynq为例与PC BIOS的对比 引言 在嵌入式系统开发中,Board Support Package (BSP)、设备树(Device Tree)和硬件抽象层(Hardware Abstraction Layer, HAL)是三个密切相关的…...
