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>

总结:

  1. 读取变量使用单括号{message},不像Vue用双括号{{}}
  2. 绑定点击事件用onClick={函数名},Vue是@click="函数名"
  3. 需要自己调用函数进行渲染,Vue是会自动渲染。
  4. 注意下面这样的写法是错误的,即只渲染部分页面。这样渲染的<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 >)}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1560420.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Linux操作系统小项目——实现《进程池》

文章目录 前言&#xff1a;代码实现&#xff1a;原理讲解&#xff1a;细节处理&#xff1a; 前言&#xff1a; 在前面的学习中&#xff0c;我们简单的了解了下进程之间的通信方式&#xff0c;目前我们只能知道父子进程的通信是通过匿名管道的方式进行通信的&#xff0c;这是因…

【gRPC】4—gRPC与Netty

gRPC与Netty ⭐⭐⭐⭐⭐⭐ Github主页&#x1f449;https://github.com/A-BigTree 笔记链接&#x1f449;https://github.com/A-BigTree/Code_Learning ⭐⭐⭐⭐⭐⭐ 如果可以&#xff0c;麻烦各位看官顺手点个star~&#x1f60a; &#x1f4d6;RPC专栏&#xff1a;https://…

力扣 前缀和

找子数组的个数了解前缀和的基础。 前缀和大致理解为到达某个位置&#xff0c;前面几个数的总和&#xff0c;即s[i1]s[i]a[i1]&#xff0c;可以通过一次循环获得。然后几个前缀和作差&#xff0c;即可得到某个位置到某个位置的和&#xff0c;根据map的键值对进行更新次数。 题…

opencv实战项目(三十一):基于同态滤波的图像亮度提升

文章目录 前言一、同态滤波二、算法实现 前言 在数字图像处理领域&#xff0c;图像亮度的调整是一项基本且至关重要的技术。它不仅关系到图像的视觉效果&#xff0c;而且在许多实际应用中&#xff0c;如医疗影像分析、卫星遥感监测、视频监控系统等&#xff0c;都扮演着关键角…

基于STM32 ARM+FPGA+AD的电能质量分析仪方案设计(一)硬件设计

电能质量分析系统硬件设计 3.1 电能质量分析系统设计要求 本系统实现对电能质量的高精度测量&#xff0c;根据国家相关电能质量分析仪器规定 标准以及对市场电能质量分析仪的分析&#xff0c;指定以下设计目标。 &#xff08; 1 &#xff09;电能质量参数测量精度&#xf…

欧科云链研究院深掘链上数据:洞察未来Web3的隐秘价值

目前链上数据正处于迈向下一个爆发的重要时刻。 随着Web3行业发展&#xff0c;公链数量呈现爆发式的增长&#xff0c;链上积聚的财富效应&#xff0c;特别是由行业热点话题引领的链上交互行为爆发式增长带来了巨量的链上数据&#xff0c;这些数据构筑了一个行为透明但与物理世…

【部署篇】Redis-01介绍‌

一、Redis介绍‌ 1、什么是Redis&#xff1f; ‌Redis&#xff0c;英文全称是Remote Dictionary Server&#xff08;远程字典服务&#xff09;&#xff0c;Redis是一个开源的、使用‌ANSI C语言编写的‌Key-Value存储系统&#xff0c;支持网络、可基于内存亦可持久化。‌ 它提…

leetcode hot100_part3_滑动窗口

滑动窗口是有一个基本的模版的&#xff0c;不要自己想当然哦~ 滑动窗口算法思想&#xff08;附经典例题&#xff09;_滑动窗口的思想-CSDN博客 滑动窗口也叫同向双指针&#xff1b;可以先看一下灵山视频&#xff1a;滑动窗口【基础算法精讲 03】_哔哩哔哩_bilibili 3.无重复字…

【unity进阶知识12】从零手搓unity存档存储数据持久化系统,实现对存档的创建,获取,保存,加载,删除,缓存,加密,支持多存档

文章目录 前言一、Unity对Json数据的操作方法一、JsonUtility方法二、Newtonsoft 二、持久化的数据路径三、数据加密/解密加密方法解密方法 四、条件编译指令限制仅在编辑器模式下进行加密/解密四、数据持久化管理器1、存档工具类2、一个存档数据3、存档系统数据类4、数据存档存…

【Oracle数据库进阶】001.SQL基础查询_查询语句

课 程 推 荐我 的 个 人 主 页&#xff1a;&#x1f449;&#x1f449; 失心疯的个人主页 &#x1f448;&#x1f448;入 门 教 程 推 荐 &#xff1a;&#x1f449;&#x1f449; Python零基础入门教程合集 &#x1f448;&#x1f448;虚 拟 环 境 搭 建 &#xff1a;&#x1…

安卓使用.9图实现阴影效果box-shadow: 0 2px 6px 1px rgba(0,0,0,0.08);

1.安卓实现阴影效果有很多种&#xff0c;一般UX设计会给以H5参数box-shadow: 0 2px 6px 1px rgba(0,0,0,0.08);这种方式提供背景阴影效果&#xff0c;这里记录一下实现过程 2.界面xml源码 <?xml version"1.0" encoding"utf-8"?> <layout xmlns…

【SEO】什么是SEO?

什么是SEO&#xff08;搜索引擎优化&#xff09;&#xff1f;为什么SEO对于⼀个⽹站⾄关重要&#xff1f; SEO 全称是搜索引擎优化&#xff08;Search Engine Optimization&#xff09; 因为我们目前开发的网址&#xff0c;需要人看到&#xff0c;除了通过宣传营销的方式展现…

kubernetes中微服务部署

微服务 问&#xff1a;用控制器来完成集群的工作负载&#xff0c;那么应用如何暴漏出去&#xff1f; 答&#xff1a;需要通过微服务暴漏出去后才能被访问 Service 是一组提供相同服务的Pod对外开放的接口借助Service&#xff0c;应用可以实现服务发现和负载均衡Service 默认只…

Docker容器简介及部署方法

1.1 Docker简介 Docker之父Solomon Hykes&#xff1a;Docker就好比传统的货运集装箱 2008 年LXC(LinuX Contiainer)发布&#xff0c;但是没有行业标准&#xff0c;兼容性非常差 docker2013年首次发布&#xff0c;由Docker, Inc开发 1.1.1什么是Docker Docker是管理容器的引…

苹果秋季盛典:iPhone 16系列引领未来科技潮流

9月10日&#xff0c;苹果公司在众人瞩目中举办了2024年的秋季特别活动&#xff0c;发布了备受期待的iPhone 16系列。 尽管网络发布会已经持续了一整年&#xff0c;但熬夜观看的果粉们仍然热情不减&#xff0c;因为每一次苹果的新品发布都代表着科技界的一次重大飞跃。 iPhone …

scau:面向对象java实验作业1-2 猜数字游戏

题目名称实验1-2 猜数字游戏题目关键字数据类型 基本输入输出 控制语句 方法题目录入时间2022/10/10 11:01:37题目内容 使用Java程序&#xff0c;项目名称&#xff1a;GuessNumberGame&#xff0c;类根据自己需要定义。 程序开始运行后&#xff0c;允许玩家进行多次猜数字的游…

使用 Docker 部署前端项目:Vue 和 React 结合 Nginx 实现静态文件托管

使用 Docker 部署前端项目&#xff1a;Vue 和 React 结合 Nginx 实现静态文件托管 Web 开发中&#xff0c;将前端项目&#xff08;例如 Vue 或 React 应用&#xff09;打包后通过 Docker 容器和 Nginx 部署是非常常见的方式。它不仅简化了部署流程&#xff0c;还能确保在不同环…

通信协议 —— RS485 讲解得好

目 录 RS-485 通信协议一、重要性二、通信实现三、其它通信方式3.1 串口通信3.2 RS232标准 四、总结 RS-485 通信协议 RS-485是一种通用的通信标准&#xff0c; RS是Recommended Standard的意思&#xff0c;是美国电子工业协会&#xff08;EIA&#xff09;在1983年批准了一个新…

【操作系统】深入探索:操作系统内核与用户进程的数据交互艺术

目录 一、数据从内核缓冲区拷贝到用户进程缓冲区&#xff0c;是谁来负责拷贝的&#xff0c;是操作系统还是用户进程&#xff1f;实际的执行者到底是谁&#xff1f;二、系统调用以及用户态内核态的相互转换1、系统调用2、用户态内核态的相互转换 三、如何形象的理解linux的虚拟地…

【华为】基于华为交换机的VLAN配置与不同VLAN间通信实现

划分VLAN&#xff08;虚拟局域网&#xff09;主要作用&#xff1a; 一、提高网络安全性 广播域隔离访问控制增强 二、优化网络性能 减少网络拥塞提高网络可管理性 sysytem-view #进入系统视图配置参数 vlan batch 10 20 #批量创建vlan LSW3: int g0/0/1 port…