React(一):初识React、类组件、jsx的基础语法
React(一)
- 一、初识React
- 1.简单介绍
- 2.React的三个依赖
- 3.Hello React案例
- 二、类组件
- 1.定义类组件并渲染
- 2.绑定事件函数(奇怪的this问题)
- 3.数组形式数据的展示(电影案例)
- 4.计数器案例
- 三、jsx语法详解
- 1.jsx的书写规范
- 2.jsx的注释
- 3.jsx嵌入变量
- 3.jsx嵌入表达式
- 4.jsx绑定属性
一、初识React
1.简单介绍
React是什么?用于构建用户界面的 JavaScript 库
React的官网文档:https://react.docschina.org/
React的特点:
1、声明式编程:声明式编程是目前整个大前端开发的模式:Vue、React、Flutter、SwiftUI;
2、组件化开发
3、多平台适配
2.React的三个依赖
1、react:包含react所必须的核心代码
2、react-dom:react渲染在不同平台所需要的核心代码
3、babel:将jsx转换成React代码的工具
依赖的引入有很多方式:
1、直接引入CDN连接
2、下载后添加本地依赖
3、脚手架npm引入
前期的学习中先在html中使用CDN引入(引入React18)
<!-- 引入三个依赖的库 -->
<!-- 1.引入react核心代码库 -->
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<!-- 2.引入渲染核心代码库 -->
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
<!-- 3.引入将jsx转换成react代码的工具库 -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
3.Hello React案例
同样作为MVVM结构的框架,React在渲染DOM的时候也有自己的方式
这里要注意,在React18版本前后,我们的写法是不一样的:
- React18之前使用
ReactDOM.render(html结构或组件,容器)
- React18之后使用
ReactDOM.createRoot(容器).render(html结构或组件)
<!-- 准备好一个容器 -->
<div id="root"></div><script type="text/babel">//渲染Hello World//React18之前使用ReactDOM.render// ReactDOM.render(<h2>Hello World</h2>, document.querySelector('#root'));//React18之后const root = ReactDOM.createRoot(document.querySelector('#root'));root.render(<h2>Hello World</h2>);
</script>
接下来是我们的点击按钮切换信息的Hello React案例完整版
<!-- 准备好一个容器 -->
<div id="root"></div><script type="text/babel">//渲染Hello World//1.定义一个变量来存储信息let message = 'Hello Word!';//React18之前使用ReactDOM.render//ReactDOM.render(<h2>Hello World</h2>, document.querySelector('#root'));//React18之后//2.定义容器const root = ReactDOM.createRoot(document.querySelector('#root'));//3.先调用一次渲染函数,渲染页面rootRender();//下面是预先定义好的函数//函数一:渲染函数function rootRender() {root.render(<div><h2>{message}</h2><button onClick={changeMsg}>点击修改信息</button></div>);}//函数二:按钮的点击事件触发函数function changeMsg() {message = 'Hello React!';console.log(message); //函数调用了,但是没有重新渲染rootRender(); //修改完后重新渲染页面}
</script>
总结,这里和Vue对比有几个不一样的地方:
1、定义容器并渲染的过程,重新渲染要自己调用渲染函数,不像Vue会自动更新页面
2、读取变量使用单括号{ name }
,不像Vue用双括号{{}}
3、html的结构要作为参数传到render
函数中,不像Vue直接编辑html结构
4、点击事件使用onClick={函数名}
,而Vue是v-on:click="函数名"
二、类组件
在React中有两种定义组件的防止,一种是类组件,另一种是函数组件,这里我们使用ES6的类来声明组件,把刚才的Hello React
案例用组件的方式呈现出来。
1.定义类组件并渲染
1、定义类组件,继承React.Component,并继承父类的属性
<!-- 准备好一个容器 -->
<div id="root"></div><script type="text/babel">//1.定义类组件class App extends React.Component {constructor() {super();}}
</script>
2、添加一个state属性,用来存储数据,名字必须叫state
<!-- 准备好一个容器 -->
<div id="root"></div><script type="text/babel">//1.定义类组件class App extends React.Component {constructor() {super();this.state = {message: 'hello world',}}}
</script>
3、定义一个render渲染函数,名字必须叫render,当我们拿到容器渲染组件时,就会自动调用这个函数,返回相应的html节点
<!-- 准备好一个容器 -->
<div id="root"></div><script type="text/babel">//1.定义类组件class App extends React.Component {constructor() {super();this.state = {message: 'hello world',}}render() {return (<div><h2>{this.state.message}</h2><button>点击切换信息</button></div>)}}
</script>
4、拿到容器,渲染组件
<!-- 准备好一个容器 -->
<div id="root"></div><script type="text/babel">//1.定义类组件class App extends React.Component {constructor() {super();//1.1添加一个state属性存储数据,名字不能改,必须叫statethis.state = {name: 'zzy',message: 'Hello World!',}}//1.3事件函数//1.2渲染函数,名字不能改,必须叫renderrender() {return (<div><h2>{this.state.message}</h2><button onClick={this.changeMsg}>点击修改信息</button></div>)}}//2.拿到容器,渲染组件let root = ReactDOM.createRoot(document.querySelector('#root'));root.render(<App/>);
</script>
2.绑定事件函数(奇怪的this问题)
这里有一个this 的问题,先复习一下严格模式的东西:严格模式
这里要知道:ES6类中的函数都会默认开启严格模式(this指向undefined)
class App {constructor(name) {this.name = name;}changeMsg() {//这里其实默认开启了严格模式console.log(this);}
}//搞清楚this的问题
let app = new App();
let out = app.changeMsg;
out(); //undefined
也就是说,只有类的实例调用类原型上的方法时,this才有指向(指向实例)
这里我们可以看到,直接给按钮绑定了一个事件函数,那么在调用的时候,调用者不是实例,this肯定不指向实例。
调用这个函数就是调用类中的函数,那么this就是undefined
,可是这样我们怎么顺着原型链访问setState
进而对数据进行更改呢?其实很简单,只需要在constructor
中改变事件函数的this指向:
//1.4保存事件函数this指向
this.changeMsg = this.changeMsg.bind(this);
<!-- 准备好一个容器 -->
<div id="root"></div><script type="text/babel">//1.定义类组件class App extends React.Component {constructor() {super();//1.1添加一个state属性存储数据,名字不能改,必须叫statethis.state = {name: 'zzy',message: 'Hello World!',}//1.4保存事件函数this指向this.changeMsg = this.changeMsg.bind(this);}//1.3事件函数changeMsg() {console.log(this);this.setState({message: 'Hello React!',})}//1.2渲染函数,名字不能改,必须叫renderrender() {return (<div><h2>{this.state.message}</h2><button onClick={this.changeMsg}>点击修改信息</button></div>)}}//2.拿到容器,渲染组件let root = ReactDOM.createRoot(document.querySelector('#root'));root.render(<App/>);
</script>
setState这个方法做了两件事:1、更改数据 => 2、重新渲染
3.数组形式数据的展示(电影案例)
方法1:遍历生成li,然后统一放到一个数组里,然后把数组直接展示
<!-- 准备好一个容器 -->
<div id="root"></div><script type="text/babel">class App extends React.Component {constructor() {super();this.state = {movies: ['星际争霸', '魔兽世界', '流浪地球', '奥里给']}}render() {//1.遍历展示数组的方法1let lis = [];for(let i = 0; i < this.state.movies.length; i++) {let movie = this.state.movies[i];let li = <li>{movie}</li>;lis.push(li);}return (<div><h2>电影名字</h2><ul>{lis}</ul></div> )}}let root = ReactDOM.createRoot(document.querySelector('#root'));root.render(<App/>);
</script>
方法2:使用map遍历数组,返回一个修改后的新数组
render() {//2.方法2,直接映射let lis = this.state.movies.map(el => <li>{el}</li>)return (<div><h2>电影名字</h2><ul>{lis}</ul></div> )
}
4.计数器案例
点击加一或减一
<div id="root"></div>
<script type="text/babel">const root = ReactDOM.createRoot(document.querySelector('#root'));class App extends React.Component {constructor() {super();this.state = {count: 0,}//改变this的指向this.add = this.add.bind(this);this.subtract = this.subtract.bind(this);}render() {let { count } = this.state;return (<div><h2>{count}</h2><button onClick={this.add}>点击+1</button><button onClick={this.subtract}>点击-1</button></div>)}//事件函数add() {this.setState({// count: this.state.count + 1count: ++this.state.count})}subtract() {this.setState({count: --this.state.count})}}root.render(<App/>);
</script>
三、jsx语法详解
我们直接把标签赋值给变量,这种写法在原来的js环境会报错,但是在jsx中(开启了babel)就不会报错,这就是一段jsx语法。
- JSX是一种JavaScript的语法扩展(eXtension)。
- 它用于描述我们的UI界面,并且其完成可以和JavaScript融合在一起使用;
- 它不同于Vue中的模块语法,你不需要专门学习模块语法中的一些指令(比如v-for、v-if、v-else、v-bind);
1.jsx的书写规范
React认为渲染逻辑本质上与其他UI逻辑存在内在耦合。
比如UI需要绑定事件,UI需要展示数据,当数据变化时UI又要更新;所以React没有把它们单独分开,而是封装成组件。那么jsx有什么书写规范呢?
1、JSX的顶层只能有一个根元素,所以我们很多时候会在外层包裹一个div原生(或者使用后面我们学习的Fragment);
render() {let { count } = this.state;return (<div><h2>{count}</h2><br/></div>)
}
2、为了方便阅读,我们通常在jsx的外层包裹一个小括号(),这样可以方便阅读,并且jsx可以进行换行书写;
3、JSX中的标签可以是单标签,也可以是双标签; 注意:如果是单标签,必须以/>
结尾,在html中不用/也行,但在这里会报错;
2.jsx的注释
在大括号中使用/**/
包裹注释
render() {let { count } = this.state;return (<div>{/*这是一段注释*/}<h2>{count}</h2></div>)
}
3.jsx嵌入变量
1、String/Number/Array这三种类型都可以正常显示(其中数组会自己拆开)
constructor() {super();this.state = {name: 'zzy', //Stringage: 18, //Numberhabits:['吃饭','睡觉'] //Array}
}render() {let { name,age,habits } = this.state;return (<div>{/*这是一段注释*/}<h2>{name}</h2><h2>{age}</h2><h2>{habits}</h2></div>)
}
2、undefined/null/Boolean这三种类型默认不会显示,因为有时候我们请求数据如果没请求到,那么肯定不能把undefined显示出来。如果非要显示,请连接字符串或toString()
constructor() {super();this.state = {a: undefined, //undefinedb: null, //nullc: true, //Boolean}
}render() {let { a, b, c } = this.state;return (<div><h2>{a}</h2><h2>{b}</h2><h2>{c}</h2></div>)
}
3、Object对象类型作为嵌入变量会报错。
constructor() {super();this.state = {friend: {name: 'ht',age: 18,}}
}render() {let { friend } = this.state;return (<div><h2>{friend}</h2> {/*报错*/}</div>)
}
3.jsx嵌入表达式
1、运算符表达式
constructor() {super();this.state = {firstName: 'zzy',lastName: 'ht',}
}render() {let { firstName, lastName } = this.state;return (<div><h2>{firstName + ' ' + lastName}</h2><h2>{30 + 20}</h2></div>)
}
2、三元表达式
constructor() {super();this.state = {num: 99,}
}render() {let { num } = this.state;return (<div><h2>{num > 10 ? 'big' : 'small'}</h2></div>)
}
3、调用函数获取返回值
constructor() {super();this.state = {num: 99,}
}render() {return (<div><h2>{this.getNum()}</h2></div>)
}getNum() {return this.state.num;
}
4.jsx绑定属性
比如img元素会有src属性、a元素会有href属性、元素可能需要绑定class、原生使用内联样式style等等,都可以动态去绑定。
1、绑定普通属性
constructor() {super();this.state = {imgUrl: "http://p2.music.126.net/L8IDEWMk_6vyT0asSkPgXw==/109951163990535633.jpg",link: 'http://www.baidu.com'}
}render() {let { imgUrl, link } = this.state;return (<div><img src={imgUrl}/><a href={link}>百度</a></div>)
}
2、绑定class样式。在React中,一般用className而不用calss(因为class是类的关键字)
.zzy {color: blue;font-size: 30px;
}
这里动态绑定类名有两种方式,一种是三元表达式+字符串拼接(或模板字符串),一种是定义一个数组,然后push进去再读取数组。
这里要注意,jsx在属性中引用数组时和在页面上展示数据时不一样:
1、属性中引用是用逗号隔开。
2、页面展示则是直接字符串相连。
constructor() {super();this.state = {active: true,msg: '动态绑定类'}
}render() {let { msg, active } = this.state;//动态绑定类名方式一let className = `zzy ${active ? 'active' : ''}`;//动态绑定类名方式二let classArr = ['zzy','ht'];if(active) classArr.push('active');return (<div><h2 className='zzy'>{msg}</h2><h2 className={className}>{msg}</h2>{/*2.绑定class*/}{/*属性动态绑定数组,转为字符串自动逗号隔开*/}{/*展示部分动态绑定数组,转为字符串自动去掉逗号*/}<h2 className={classArr.join(' ')}>{msg}</h2></div>)
}
3、绑定style样式,这里要使用对象的形式,属性名采用驼峰命名,这里和我们刚才提到的html内容展示是不一样的,内容展示用对象会报错,而属性绑定这里不会报错,即双括号{{}}
constructor() {super();this.state = {msg: '动态绑定style'}
}render() {return (<div>{/*3.绑定style*/}<h2 style={{color:'blue',fontSize:'36px'}}>{this.state.msg}</h2></div>)
}
相关文章:

React(一):初识React、类组件、jsx的基础语法
React(一)一、初识React1.简单介绍2.React的三个依赖3.Hello React案例二、类组件1.定义类组件并渲染2.绑定事件函数(奇怪的this问题)3.数组形式数据的展示(电影案例)4.计数器案例三、jsx语法详解1.jsx的书…...
2023-2-24 刷题情况
获取单值网格的最小操作数 题目描述 给你一个大小为 m x n 的二维整数网格 grid 和一个整数 x 。每一次操作,你可以对 grid 中的任一元素 加 x 或 减 x 。 单值网格 是全部元素都相等的网格。 返回使网格化为单值网格所需的 最小 操作数。如果不能,返…...

测试员拿到新项目怎么着手测试?不要慌,照做准没错
一、目标 结合公司现有的项目情况制定合理规范的测试流程,提高测试效率和产品质量,尽可能减少客户对产品的问题反馈, 核心还是要加强项目组成员之间的工作交流和沟通,保证整个项目的高效率的按质按量的交付。 二、测试流程说明…...

通过cfssl自签证书https证书
背景 公司内部自建Web服务,通过自签CA,然后签发https证书 工具地址: GitHub - cloudflare/cfssl: CFSSL: Cloudflares PKI and TLS toolkit 使用步骤: 1. 在release页面中下载最新的二进制包,我使用的是1.5的解压并重命名二进制文件 tar…...

openEuler部署Ceph集群(块存储)
openEuler部署Ceph集群1 目标2 环境2.1 服务器信息2.2 软件信息3 部署流程3.1 获取系统镜像3.2 创建虚拟机3.3 配置虚拟机3.3.1 配置互信3.3.2 关闭防火墙3.3.3 配置免密登录3.3.4 配置NTP3.3.4.1 安装NTP服务3.3.4.2 配置NTP服务端3.3.4.3 配置NTP客户端3.3.4.4 启动NTP服务3.…...

npm install vue2-ace-editor 安装报错
npm install vue2-ace-editor 安装报错,如下图 目录 npm install vue2-ace-editor 安装报错,如下图 🧨🧨🧨解决方法:在命令后面加上 神秘代码 npm install vue2-ace-editor --save --legacy-peer-deps &a…...

【PyQt5图形界面编程(2)】:创建工程
创建工程 一、创建工程二、开始开发1、运行Qt5Designer,创建QT窗口2、运行pyUIC,转换xx.ui成xx.py3、main.py中引用xx.py中的类4、打包main.py成main.exe来发布5、执行终端报警处理方法三、其他(如果涉及)1、配置环境变量一、创建工程 采用虚拟环境来创建工程 相关的paka…...
ansible实战应用系列教程9:管理inclusions
ansbile实战应用系列教程8:管理inclusions InclusionsIncluding TasksIncluding VariablesInclusions 当处理复杂或冗长的剧本时,管理员可以使用单独的文件将任务和变量列表划分为更小的部分,以便于管理。在playbook中引入外部任务文件和变量有多种方法。 方法一:tasks使用…...

MyBatis学习笔记(五) —— MyBatis获取参数值的两种方式
5、MyBatis获取参数值的两种方式 MyBatis获取参数值的两种方式:${} 和 #{} ${} 的本质就是字符串拼接, #{} 的本质就是占位符赋值 ${} 使用字符串拼接的方式拼接sql,若为字符串类型或日期类型的字段进行赋值时,需要手动加单引号&a…...

go module构建项目
在go 1.11版本中引入了Go Module内置的包管理模块,是GOPATH的替代品,集成了版本控制和软件包分发支持的功能。即go使用modules管理依赖,项目依赖构建时不需要再依赖GOPATH环境变量。 要使用go module首先要激活modules .升级go到1.11版本 .这…...
已经准备上千道软件测试面试题了,建议大家收藏!!!还有视频详解!
2023华为软件测试笔试面试真题,抓紧收藏不然就看不到了_测试小鬼的博客-CSDN博客_华为软件测试工程师面试题1、对计算机软件和硬件资源进行管理和控制的软件是(D)A.文件管理程序B.输入输出管理程序C.命令出来程序D.操作系统2、在没有需求文档…...

C++设计模式(19)——访问者模式
亦称: Visitor 意图 访问者模式是一种行为设计模式, 它能将算法与其所作用的对象隔离开来。 问题 假如你的团队开发了一款能够使用巨型图像中地理信息的应用程序。 图像中的每个节点既能代表复杂实体 (例如一座城市)…...

ChatGPT 的工作原理:机器人背后的模型
这篇对支持 ChatGPT 的机器学习模型的温和介绍,将从大型语言模型的介绍开始,深入探讨使 GPT-3 得到训练的革命性自我注意机制,然后深入研究人类反馈的强化学习,使 ChatGPT 与众不同的新技术。 大型语言模型 ChatGPT 是一类被称…...

FreeRTOS入门(04):中断、内存、追踪与调试
文章目录目的中断内存堆(heap)栈(stack)断言调试总结目的 有了前面的几篇文章 FreeRTOS 基本上已经可以在项目中使用上了: 《FreeRTOS入门(01):基础说明与使用演示》 《FreeRTOS入门…...

【C语言】带你彻底理解指针(1)
✨✨✨✨如果文章对你有帮助记得点赞收藏关注哦!!✨✨✨✨ 文章目录指针的介绍:一、简单指针🌈1.1 指针的定义与使用1.2 指针与数组二、指针数组✨三、数组指针🌞3.1 数组指针的定义3.2 ”数组名“与”&数组名“3.…...
C/C++ 中 JSON 库的使用 (CJSON/nlohmann)
C/C 中 JSON 库的使用 (CJSON/nlohmann)概述cjson基本操作从(字符指针)缓冲区中解析出JSON结构转成成JS字符串(将传入的JSON结构转化为字符串)将JSON结构所占用的数据空间释放JSON 值的创建创建一个值类型的数据创建一个对象(文档)…...

【Opencv项目实战】目标检测:自动检测出现的所有动态目标
文章目录一、项目思路二、算法详解2.1、计算两个数组或数组与标量之间的每个元素的绝对差。2.2、轮廓检测 绘制物体轮廓 绘制矩阵轮廓2.3、连续窗口显示2.4、读取视频,显示视频,保存视频三、项目实战:实时动态目标检测实时动态目标检测一、…...

活动报名:Tapdata Cloud V3 最新功能全解与核心应用场景演示
作为中国的 “Fivetran/Airbyte”, Tapdata Cloud 自初版公测以来,已累积10,000 注册用户。核心场景包括 Any Source → Any Target 的实时数据库同步、数据入湖入仓,以及通用 ETL 处理等。近期,功能特性全面优化的 Tapdata Cloud V3 也已开放…...

人工智能AI威武,爱也……恨也……
人工智能AI威武,爱也!恨也!!它会创作会代码,从它那儿能仿到更好的思维;多它那里可以学到更好的代码。它聪慧全能,成为一坨人偷懒神器;变成“智者”作弊的“倚天屠龙”!&a…...

SpringBoot-基础篇
SpringBoot基础篇 在基础篇中,我给学习者的定位是先上手,能够使用SpringBoot搭建基于SpringBoot的web项目开发,所以内容设置较少,主要包含如下内容: SpringBoot快速入门SpringBoot基础配置基于SpringBoot整合SSMP…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...

docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...

基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...

Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...

2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...

【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...