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…...

测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

【Linux】自动化构建-Make/Makefile
前言 上文我们讲到了Linux中的编译器gcc/g 【Linux】编译器gcc/g及其库的详细介绍-CSDN博客 本来我们将一个对于编译来说很重要的工具:make/makfile 1.背景 在一个工程中源文件不计其数,其按类型、功能、模块分别放在若干个目录中,mak…...

C++_哈希表
本篇文章是对C学习的哈希表部分的学习分享 相信一定会对你有所帮助~ 那咱们废话不多说,直接开始吧! 一、基础概念 1. 哈希核心思想: 哈希函数的作用:通过此函数建立一个Key与存储位置之间的映射关系。理想目标:实现…...

Redis上篇--知识点总结
Redis上篇–解析 本文大部分知识整理自网上,在正文结束后都会附上参考地址。如果想要深入或者详细学习可以通过文末链接跳转学习。 1. 基本介绍 Redis 是一个开源的、高性能的 内存键值数据库,Redis 的键值对中的 key 就是字符串对象,而 val…...
Android屏幕刷新率与FPS(Frames Per Second) 120hz
Android屏幕刷新率与FPS(Frames Per Second) 120hz 屏幕刷新率是屏幕每秒钟刷新显示内容的次数,单位是赫兹(Hz)。 60Hz 屏幕:每秒刷新 60 次,每次刷新间隔约 16.67ms 90Hz 屏幕:每秒刷新 90 次,…...