React(一) 认识React、熟悉类组件、JSX书写规范、嵌入变量表达式、绑定属性
文章目录
- 一、初始React
- 1. React的基本认识
- 2. Hello案例
- 2.1 三个依赖
- 2.2 渲染页面
- 2.3 hello案例完整代码
- 二、类组件
- 1. 封装类组件
- 2. 组件里的数据
- 3. 组件里的函数 (重点)
- 4. 案例练习
- (1) 展示电影列表
- 三、JSX语法
- 1. 认识JSX
- 2. JSX书写规范及注释
- 3. JSX嵌入变量作为子元素
- 4. JSX嵌入表达式
- 5. JSX绑定属性
- (1) title,src,href属性
- (2) 绑定class
- (3) 绑定style样式
一、初始React
1. React的基本认识
React是:用于构建用户界面的JavaScript库;
React官网文档:React官网
React的三个特点:
(1) 声明式编程
(2) 组件化开发
和Vue一样,将复杂的页面分解成一个个组件
(3) 多平台适配
2013 React发布之初是开发Web页面
2015 推出ReactiveNative用于开发移动端平台
2017 推出ReactVR,用于开发虚拟显示Web应用程序。
2. Hello案例
2.1 三个依赖
React需要引入三个依赖,
(1) react:包含react所必须的核心代码
(2) react-dom:react渲染在不同平台所需要的核心代码
(3) babel:将jsx转换成React代码的工具
引入的方式有三种
(1) CDN引入
(2) 下载引入
(3) npm下载引入(脚手架)
本案例中采用cdn引入
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script><script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script><!-- babel --><script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
拓展:
Babel是目前前端使用非常广泛的编译器;可以将Es6、React JSX语法、TypeScript等语法转化为普通的JavaScript代码,让浏览器认识代码并运行。
2.2 渲染页面
React18版本前后,渲染Dom的写法不同:
React18之前: ReactDOM.render(渲染的内容,容器)
React18之后: ReactDOM.createRoot(容器).render(渲染的内容)
渲染的内容指的是html结构或组件
容器:也就是指定在哪里渲染页面
<div id="root"></div><!-- 指定type="text/babel";babel才会解析这里的jsx语法代码 --><script type="text/babel"> // 渲染Hello World// React18之前://ReactDOM.render(<h2>Hello World</h2>, document.querySelector("#root"))// React18之后:const root = ReactDOM.createRoot(document.querySelector("#root"))root.render(<h2>Hello World</h2>)</script>
2.3 hello案例完整代码
<!-- 定义一个容器 --><div id="root"></div><!-- 添加依赖:三个依赖 --><script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script><script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script><script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script><script type="text/babel">const root = ReactDOM.createRoot(document.querySelector("#root"))// 1. 定义内容变量let message = 'Hello World'// 2. 初始化渲染页面rootRender()// 渲染页面函数,为了在后续更新页面时方便渲染,将渲染封装成一个函数function rootRender () {root.render((<div><h2>{message}</h2><button onClick={btnClick}>修改内容</button></div>))}// 按钮监听事件function btnClick () {// 1.修改数据message = "Hello React"// 2. 重新渲染rootRender()}</script>
总结:
- 读取变量使用单括号
{message}
,不像Vue用双括号{{}}
- 绑定点击事件用
onClick={函数名}
,Vue是@click="函数名"
- 需要自己调用函数进行渲染,Vue是会自动渲染。
- 注意下面这样的写法是错误的,即只渲染部分页面。这样渲染的
<h2>
会将button
覆盖掉
二、类组件
React中组件有两类:类组件和函数式组件;
1. 封装类组件
(1) 定义一个类(继承React.Component
),类名必须大写(类名就是组件名),小写会被认为是HTML元素。
(2) 实现当前组件的render函数:render返回的jsx内容,就是之后React会渲染的内容。
<script type="text/babel">// 定义组件Appclass App extends React.Component {constructor() {super()}// 组件数据// 组件方法(实例方法)// 渲染到界面上,render函数render () {return <h2>hello world</h2>}}// 将组件渲染到界面上const root = ReactDOM.createRoot(document.querySelector("#root"))root.render(<App />) // App根组件渲染到界面上</script>
执行 root.render(<App />)
语句时,会调用类中的render
方法,进行界面渲染。
2. 组件里的数据
数据分为两类:参与界面更新、不参与界面更新。
参与界面更新的数据也叫参与数据流,定义在当前对象的state中,写在构造函数里。
使用该数据时:this.state.变量名称
修改数据时: this.setState(....)
class App extends React.Component {constructor() {super()// 定义数据this.state = {message: "Hello World",}}// 渲染时使用数据render () {return (<div><h2>{this.state.message}</h2><button>修改内容</button></div>)}}
3. 组件里的函数 (重点)
需要提前看一下严格模式里的this指向问题:博主DantinZhang总结的严格模式
在严格模式下,函数在独立调用时(不是通过某个对象调用),this的值为undefined;
babel在编译代码时,自动加上了use strict
,即设置为严格模式;
需要知道:ES6类中的函数都会默认开启严格模式
<script type="text/babel">
class App {constructor(name) {this.name = name;} btnClick () {//这里其实默认开启了严格模式,console.log('btn:', this);}
}
//搞清楚this的问题
let app = new App();
let out = app.btnClick ;
out(); //这里打印undefined,是因为函数里默认开启严格模式function fun () {console.log('fun', this);}fun() // 这里打印undefined,是因为babel编译时加了严格模式</script>
将 type="text/babel"
去掉之后,out()
是类里的函数,还是打印undefined
;而fun()
不是类里的函数,去掉babel后,打印Window。
本案例需要在点击事件的回调函数里修改message
的值
btnClick () {// 通过this.setState修改message的值this.setState({message: 'Hello React'})}
问题是:btnClick
里的this
不指向实例对象,指向undefined
解决方式一:
绑定回调函数时,通过bind改变this的指向。
解决方式二:在构造函数里改变this指向;这也是官方推荐的写法。
<!-- 定义一个容器 -->
<div id="root"></div><script type="text/babel">// 1. 定义类组件class App extends React.Component {constructor() {super()// 1.1 定义组件数据,添加一个state属性存储数据,名字不能改,必须叫statethis.state = {message: "Hello World",}// 1.4 对需要绑定的方法,提前绑定好thisthis.btnClick = this.btnClick.bind(this)}// 1.3 组件方法(实例方法)btnClick () {console.log('btn:', this);this.setState({message: 'Hello React'})}// 1.2 渲染函数,名字不能改,就叫renderrender () {return (<div><h2>{this.state.message}</h2><button onClick={this.btnClick}>修改内容</button></div>)}}// 2. 将组件渲染到界面上const root = ReactDOM.createRoot(document.querySelector("#root"))root.render(<App />) // App根组件渲染到界面上
</script>
setState
方法来自于继承的React.Componetn
,其内部完成了两件事:
(1) 将state里的message值改掉;(2) 自动重新执行render函数
4. 案例练习
案例多写几遍,熟悉结构
(1) 展示电影列表
<!-- 定义一个容器 --><div id="root"></div><script type="text/babel">// 1. 定义类组件class App extends React.Component {constructor() {super()this.state = {movies: ['飞屋环游记', '夏日友情天', '玩具总动员']}} render(){...}}// 2. 渲染组件const root = ReactDOM.createRoot(document.querySelector('#root'))root.render(<App />)</script>
渲染方式一:循环遍历
render () {// 遍历展示数据let lis = []for (let i = 0; i < this.state.movies.length; i++) {let ele = <li>{this.state.movies[i]}</li>lis.push(ele)}return (<div><h2>电影名字</h2><ul>{lis}</ul></div>)}
渲染方式二:map函数
// 渲染方式二,maprender () {let lis = this.state.movies.map(item => <li>{item}</li>)return (<div><h2>电影名字</h2><ul>{lis}</ul></div>)}
三、JSX语法
1. 认识JSX
// 1. 定义元素内容const element = <div>Hello World</div>// 2. 渲染const root = ReactDOM.createRoot(document.querySelector('#root'))root.render(element)
在js中,将一段html直接赋值给变量element会出现语法错误。而在jsx语法中(开启babel:type="text/babel"
),第2行代码不会报错。
- JSX是一种JavaScript的语法扩展(eXtension),也称为JavaScript XML
- 它用于描述我们的UI界面,并且它可以和JavaScript融合在一起使用;
- 它不同于Vue中的模块语法,不需要专门学习模块语法中的一些指令(比如v-for、v-if、v-else、v-bind);
2. JSX书写规范及注释
书写规范:
(1) JSX只能有一个根元素,一般会在外层包裹一个<div>
(或者使用后边学习的Fragment)
(2) 为了方便阅读,有多行代码时,会在jsx外层包裹一个小括号
(3) JSX中的标签可以是单标签或双标签
注释
语法:{/*注释内容...*/}
render () {return (<div>{/*JSX的注释写法*/}// JSX的注释写法---这样写仍旧会展示到页面上<h2>当前计数为:{this.state.number}</h2></div>)}
3. JSX嵌入变量作为子元素
子元素就是标签里的内容。<h2 title='111'>aaa</h2>
aaa是子元素,title是标签属性。
(1). 当变量是Number,String,Array类型时,可以直接显示
this.state = {// 1. 变量是Number,String,Array类型number: 0,name: 'tom',movies: ['加勒比海盗', '百鸟朝凤', '飞屋环游记'],}render () {const { number, name, movies } = this.statereturn (<div>{/*1. 变量是Number,String,Array时,直接显示*/}<h2>{number}</h2><h2>{name}</h2><h2>{movies}</h2></div>)}
(2). 当变量是null,undefined,Boolean类型时,不显示
若要显示,则需要转换成字符串(比如toString
方法、空字符串拼接
、String(变量)
)
this.state = {// 2. 变量是null, undefined, Booleanaaa: null,bbb: undefined,ccc: true,}render () {const { aaa, bbb, ccc } = this.statereturn (<div>{/*2. 变量是null, undefined, Boolean时,内容为空*/}<h2>{aaa}</h2><h2>{bbb}</h2><h2>{ccc}</h2>{/*2 若要显示,则需要转换成字符串*/}<h2>{aaa + ''}</h2><h2>{String(bbb)}</h2><h2>{ccc.toString()}</h2></div>)}
(3). Object对象类型的变量不能作为子元素,会报错
this.state = {friend: {name: 'jerry'}}render () {const { friend } = this.statereturn (<div><h2>{friend}</h2></div>)}
可以写对象里具体的属性
{/*<h2>{friend}</h2>*/}<h2>{friend.name}</h2> // jerry<h2>{Object.keys(friend)[0]}</h2> // name
4. JSX嵌入表达式
运算表达式,三元运算符,执行函数
this.state = {firstName: '张',lastName: '三',age: 20,movies: ["流浪地球", "星际穿越", "独行月球"]}// 渲染函数render () {const { firstName, lastName } = this.stateconst fullName = firstName + ' ' + lastNameconst { age } = this.stateconst ageText = age >= 18 ? "成年人" : "未成年人"return (<div>{/*1 运算表达式*/}<h2>{10 + 20}</h2><h2>{firstName + '' + lastName}</h2><h2>{fullName}</h2>{/*2 三元运算符*/}<h2>{ageText}</h2><h2>{age > 18 ? '成年人' : '未成年人'}</h2>{/*3 执行一个函数*/}<ul>{this.state.movies.map(movie => <li>{movie}</li>)}</ul><ul>{this.getMovieEls()}</ul></div >)}getMovieEls () {const liEls = this.state.movies.map(movie => <li>{movie}</li>)return liEls}
5. JSX绑定属性
(1) title,src,href属性
this.state = {title: "哈哈哈",imgURL: "https://ts1.cn.mm.bing.net/th/id/R-C.95bc299c3f1f0e69b9eb1d0772b14a98?rik=W5QLhXiERW4nLQ&riu=http%3a%2f%2f20178405.s21i.faiusr.com%2f2%2fABUIABACGAAgoeLO-wUo4I3o2gEw8Qs4uAg.jpg&ehk=N7Bxe9nqM08w4evC2kK6yyC%2bxIWTjdd6HgXsQYPbMj0%3d&risl=&pid=ImgRaw&r=0",href: "https://www.baidu.com",
}
// 渲染函数render () {const { title, imgURL, href } = this.statereturn (<div><h2 title={title}>h2 标题</h2><img src={imgURL} /><a href={href}>百度链接</a></div >)}
(2) 绑定class
需求:给h2
绑定 abc cba
, 当isActive
为true时,绑定active
,否则不绑。
注意:React绑定类名时,用className,而不是class(用class会有警告)
(1)方式一:拼接字符串
this.state = {isActive: false}render () {const { isActive } = this.state// 1. 绑定方法一:字符串拼接const className = `abc cba ${ isActive ? 'active' : '' }`return (<div><h2 className="abc cba">哈哈哈哈</h2>{/*动态绑定*/}<h2 className={className}>哈哈哈哈</h2></div >)}
缺点是,当isAcrtve
为false时,类名里会多出一个空格
(2) 方式二:将所有的class类名放到数组里
render () {const { isActive } = this.state// 2. 绑定方法二:将所有的class放到数组里const className = ['abc', 'cba']// isActive为true就添加active类名if (isActive) className.push('active')return (<div><h2 className={className.join('')}>哈哈哈哈</h2></div >)}}
当
className
为数组时:
类名解析出来有逗号:<h2 class="abc,cba">哈哈哈哈</h2>
所以需要.join进行处理
(3)方式三:第三方库classnames -> npm install classnames;后续再补充
(3) 绑定style样式
绑定style样式时,需要使用对象形式,属性名采用驼峰命名;
注意:JSX绑定子元素时不可以用对象,这里是绑定属性,可以用对象
this.state = {objStyle: { color: "red", fontSize: "30px" }}render () {const {objStyle } = this.statereturn (<div>{ /* 绑定style属性: 绑定对象类型,第一个{}是语法,第二个{}表示对象 */}<h2 style={{ color: "red", fontSize: "30px" }}>呵呵呵呵</h2><h2 style={objStyle}>呵呵呵呵</h2></div >)}
相关文章:

React(一) 认识React、熟悉类组件、JSX书写规范、嵌入变量表达式、绑定属性
文章目录 一、初始React1. React的基本认识2. Hello案例2.1 三个依赖2.2 渲染页面2.3 hello案例完整代码 二、类组件1. 封装类组件2. 组件里的数据3. 组件里的函数 (重点)4. 案例练习(1) 展示电影列表 三、JSX语法1. 认识JSX2. JSX书写规范及注释3. JSX嵌入变量作为子元素4. JS…...

计算机网络 2024 11 10
计算机网络 - 知乎计算机网络(四)—— 网络层(1、2):网络层概述、网络层提供的两种服务_以下属于网络层范畴的是a透明传输比特流b媒体接入控制c ip地址d-CSDN博客 湖科大教书匠的个人空间-湖科大教书匠个人主页-哔哩哔…...

King3399(ubuntu文件系统)风扇驱动
该文章仅供参考,编写人不对任何实验设备、人员及测量结果负责!!! 0 引言 文章主要介绍King3399(ubuntu文件系统)风扇控制(GPIO),涉及king-rk3399.dts设备树修改&#x…...

前端开发笔记--html 黑马程序员2
文章目录 前端常用标签一、标题标签二、段落标签和换行标签和水平线标签三、文本格式化标签四、盒子标签五、图像标签六、连接标签七、注释和特殊字符 八、表格标签的基本使用九、列…...

django(二):定义第一个函数及url介绍
1.定义index函数 """ django里的第一个函数必须是request,不写会报错 """def index(request):return HttpResponse("Hello, world. Youre at the index of djangoProject.")注意! ①.index函数里的形参必须为request ②.r…...

66 消息队列
66 消息队列 基础概念 参考资料:消息队列MQ快速入门(概念、RPC、MQ实质思路、队列介绍、队列对比、应用场景) 消息队列就是一个使用队列来通信的组件;为什么需要消息队列? 在实际的商业项目中,它这么做肯…...

【系统分析师】-案例篇-信息系统安全
1、信息系统的安全威胁 来自于物理环境、通信链路、网络系统、操作系统、应用系统以及管理等多个方面。 物理安全威胁是指对系统所用设备的威胁,如自然灾害、电源故障、数据库故障和设备被盗等造成数据丢失或信息泄漏。 通信链路安全威胁是指在传输线路上安装窃…...

基于极光优化算法(Polar Lights Optimization, PLO)的多无人机协同三维路径规划(提供MATLAB代码)
一、极光优化算法介绍 极光优化算法(Polar Lights Optimization, PLO)是2024年提出的一种新型的元启发式优化算法,它从极光这一自然现象中汲取灵感。极光是由太阳风中的带电粒子在地球磁场的作用下,与地球大气层中的气体分子碰撞…...

TypeScript类型体操5
类型编程主要的目的就是对类型做各种转换,如何对类型做修改? TypeScript 类型系统支持 3 种可以声明任意类型的变量: type、infer、类型参数。 type:类型别名,声明一个变量存储某个类型。type t Promise<number&g…...

搭建广告展示页Start
想自定义广告- 场景: app冷启动/热启动-有广告需求,就打开广告页,没有的话就去登录或者主页 有的app有的需要广告页,有的不需要,搞个配置呗!!! 通过首选项配置存储我们的一些常用…...

无极低码基础版(部署版)课程计划
基础版(部署版)使用指南 特点 简单:1分钟学会无需编码:会SQL即可适合人群:纯小白0代码写服务1. 本地环境安装 JDKMySQLRedisTomcat2. 环境变量配置 JDK无极低码授权3. 配置文件修改 4. 服务启动 5. 服务发布示例 服务手动注册SQL语句注册6. 新增接口示例 正常新增非空参…...

Word文档功能快捷键大全
以下是 Microsoft Word 的全面快捷键大全,涵盖了文档操作、文本编辑、格式化、导航等多种功能,帮助你提高工作效率。 Word 全面快捷键和快捷方式表 功能类别快捷键/快捷方式功能描述基本文档操作Ctrl N新建文档Ctrl O打开文档Ctrl S保存文档F12另存…...

题目:1297. 子串的最大出现次数
> Problem: 1297. 子串的最大出现次数 题目:1297. 子串的最大出现次数 题目描述 给定一个字符串 s,要求找到满足以下条件的任意子串的出现次数,并返回该子串的最大出现次数: 子串中不同字母的数目必须小于等于 maxLetters。…...

一力破万法,高并发系统优化通解思路
高并发系统优化:从理论到Java实践 针对高并发场景,以下策略能够有效提升系统的稳定性和响应速度: 加集群 结果:通过增加服务器数量,实现负载均衡,提高系统整体处理能力。过程: 配置负载均衡器&…...

P8635 [蓝桥杯 2016 省 AB] 四平方和
对于一个给定的正整数,可能存在多种平方和的表示法。 要求你对 44个数排序使得 0≤a≤b≤c≤d。 输入 #1复制 5 输出 #1 0 0 1 2 输入 #2 12 输出 #2 0 2 2 2 输入 #3 773535 输出 #3 1 1 267 838 代码 #include<bits/stdc.h> using namespace …...

ElasticSearch是什么?
1.概述 Elasticsearch 是一个基于 Apache Lucene 构建的开源分布式搜索引擎和分析引擎。它专为云计算环境设计,提供了一个分布式的、高可用的实时分析和搜索平台。Elasticsearch 可以处理大量数据,并且具备横向扩展能力,能够通过增加更多的硬…...

2024年四非边缘鼠鼠计算机保研回忆(记录版 碎碎念)
Hi,大家好,我是半亩花海。写下这篇博客时已然是金秋十月,心中的石头终于落地,恍惚间百感交集。对于保研这条路,我处于摸着石头过河、冲击、随缘的这些状态。计算机保研向来比其他专业难,今年形势更是艰难。…...

clickhouse常用脚本语句
1.创建库和删除库 drop database IF EXISTS rt_db CREATE DATABASE rt_db ENGINE = Ordinary; CREATE DATABASE rt_db ENGINE = Atomic;2.创建表 CREATE TABLE IF NOT EXISTS intellect_alarm_info ( `id` UInt64 , `client_info_id...

GeneMark软件的秘钥gm_key失效怎么办?
GeneMark软件的gm_key失效怎么办 1. 下载网址(为软件的下载界面):http://topaz.gatech.edu/GeneMark/license_download.cgi 2.下载界面 根据自己的需求下载对应的版本和类型的gm_key秘钥 3.填写注册信息 4. 点击下载软件和密钥 5. 将秘钥…...

线性回归逻辑回归-笔记
一、线性回归(Linear Regression) 1. 定义 线性回归是一种用于回归问题的算法,旨在找到输入特征与输出值之间的线性关系。它试图通过拟合一条直线来最小化预测值与真实值之间的误差。 2. 模型表示 线性回归模型假设目标变量(输…...

如何将数据从 AWS S3 导入到 Elastic Cloud - 第 1 部分:Elastic Serverless Forwarder
作者:来自 Elastic Hemendra Singh Lodhi 这是多部分博客系列的第一部分,探讨了将数据从 AWS S3 导入 Elastic Cloud 的不同选项。 Elasticsearch 提供了多种从 AWS S3 存储桶导入数据的选项,允许客户根据其特定需求和架构策略选择最合适的方…...

Linux基础-正则表达式
正则表达式概述 正则表达式是处理字符串的一种工具,可以用于查找、删除、替换特定的字符串,主要用于文件内容的处理。与之不同的是,通配符则用于文件名称的匹配。正则表达式通过使用特殊符号,帮助用户轻松实现对文本的操作。 一…...

【HTML格式PPT离线到本地浏览】
文章目录 概要实现细节小结 概要 最近在上课时总是出现网络不稳定导致的PPT无法浏览的情况出现,就想到下载到电脑上。但是PPT是一个HTML的网页,无法通过保存网页(右键另存为mhtml只能保存当前页)的形式全部下载下来,试…...

如何在Vue项目中封装axios
文章目录 一、axios简介基本使用 二、封装axios的原因三、封装axios的方法1. 设置接口请求前缀2. 设置请求头和超时时间3. 封装请求方法4. 添加请求拦截器5. 添加响应拦截器小结 一、axios简介 axios 是一个基于 XMLHttpRequest 的轻量级HTTP客户端,适用于浏览器和…...

linux 配置ssh免密登录
一、 cd /root/.ssh/ #不存在就创建mkdir /root/.ssh ssh-keygen #连续按4个回车 ll二、将公钥发送到目标服务器下 #公钥上传到目标服务器 ssh-copy-id root192.168.31.142 #回车完也是要输入密码的 #测试一下免密登录: ssh root192.168.31.142 成功...

【AI绘画】Midjourney进阶:三分线构图详解
博客主页: [小ᶻZ࿆] 本文专栏: AI绘画 | Midjourney 文章目录 💯前言💯什么是构图为什么Midjourney要使用构图 💯三分线构图特点使用场景提示词书写技巧测试 💯小结 💯前言 【AI绘画】Midjourney进阶&a…...

享元模式(C++)
定义:享元模式是一种结构型设计模式,它使用共享对象,用以尽可能减少内存使用和提高性能。享元模式通过共享已经存在的对象实例,而不是每次需要时都创建新对象实例,从而避免大量重复对象的开销。 对比: 与单…...

开发一个UniApp需要多长时间
开发一个UniApp所需的时间因项目的规模、复杂度、开发团队的经验水平以及开发过程中的需求变更等多种因素而异。因此,很难给出一个确切的时间范围。然而,我们可以从以下几个方面来大致估算开发时间: 项目规划与需求分析: 在项目开…...

服务器源IP暴露后的安全风险及防御措施
在互联网安全领域,服务器的源IP地址泄露可能成为黑客攻击的切入点。本文将列举十种常见的攻击类型,并提供相应的防御建议,帮助管理员们更好地保护服务器免受潜在威胁。 一、引言 服务器源IP地址的暴露意味着攻击者可以直接针对服务器发起攻击…...

YoloV8改进策略:BackBone改进|CAFormer在YoloV8中的创新应用,显著提升目标检测性能
摘要 在目标检测领域,模型性能的提升一直是研究者和开发者们关注的重点。近期,我们尝试将CAFormer模块引入YoloV8模型中,以替换其原有的主干网络,这一创新性的改进带来了显著的性能提升。 CAFormer,作为MetaFormer框架下的一个变体,结合了深度可分离卷积和普通自注意力…...