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">
     // 定义组件App
    class 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属性存储数据,名字不能改,必须叫state
      this.state = {
        message: "Hello World",
      }
      // 1.4 对需要绑定的方法,提前绑定好this
      this.btnClick = this.btnClick.bind(this)
    }

    // 1.3 组件方法(实例方法)
    btnClick () {
      console.log('btn:', this);
      this.setState({
        message: 'Hello React'
      })
    }

    // 1.2 渲染函数,名字不能改,就叫render
    render () {
      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函数

   // 渲染方式二,map
   render () {
     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.state
   return (
     <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, Boolean
     aaa: null,
     bbb: undefined,
     ccc: true,
   }
  render () {
    const { aaa, bbb, ccc } = this.state
    return (
      <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.state
   return (
     <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.state
    const fullName = firstName + ' ' + lastName
    const { age } = this.state
    const 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.state
   return (
     <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.state
     return (
       <div>
         { /* 绑定style属性: 绑定对象类型,第一个{}是语法,第二个{}表示对象 */}
         <h2 style={{ color: "red", fontSize: "30px" }}>呵呵呵呵</h2>
         <h2 style={objStyle}>呵呵呵呵</h2>
       </div >
     )
   }

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

android app执行shell命令视频课程补充android 10/11适配-千里马android

(https://blog.csdn.net/learnframework/article/details/120103471) https://blog.csdn.net/learnframework/article/details/120103471 hi&#xff0c;有学员在学习跨进程通信专题课程时候&#xff0c;在实战app执行一个shell命令的项目时候&#xff0c;对课程本身的android …

推荐算法的学习

文章目录 前言1、模型1.1 从本领域模型的发展历史中学习1.1.1 在历史中总结发展规律和趋势1.1.2 发现模型之间的共性&#xff0c;方便记忆 1.2 从其他领域的发展中学习1.2.1 注意力机制1.2.2 残差网络 1.3 实践该怎么办&#xff1f; 2、 特征2.1 数据源的选择与建立2.2 特征构造…

Element中el-table组件设置max-height右侧出现空白列的解决方法

之前就出现过这个情况&#xff0c;没理过&#xff0c;因为不影响啥除了不美观...但今天看着实在是难受&#xff0c;怎么都不顺眼(可能是我自己烦躁--) 试了很多网上的方法&#xff0c;都不得行&#xff0c;后面发现了这篇文章&#xff0c;解决了! 感谢&#xff01; Element中t…

PageHelper循环依赖问题

1. 问题 2. 原因 项目中SpringBoot的版本为2.7.18。 SpringBoot2.6.x后不推荐使用循环依赖&#xff0c;也就是说从2.6.x版本开始&#xff0c;如果项目里还存在循环依赖&#xff0c;SpringBoot将拒绝启动&#xff01; 3. 解决 去pageHelper github看&#xff0c;才看到新版本…

Pandas缺失值处理

目录 NaN 加载包含缺失的数据 查看缺失值 通过info函数查看缺失值 通过isnull函数查看缺失值 通过notnull函数查看缺失值 通过isnull().sum()统计空值 缺失值处理 准备数据 dropna删除缺失值 fillna平均值填充缺失值 fillna前后值填充缺失值 interpolate线性插值 …

C++中的vector二维数组(全面详解)

目录 二维数组概念&#xff1a; 二维数组格式&#xff1a; 二维数组的初始化&#xff1a; 在创建的时候就进行初始化&#xff1a; resize初始化&#xff1a; 构造v的时候只给行数&#xff0c;列数用resize开辟 构造v的时候不给行数不给列数&#xff0c;都用resize来开辟…

Java中使用protobuf

一、简介 Protocal Buffers(简称protobuf)是谷歌的一项技术&#xff0c;用于结构化的数据序列化、反序列化。 Protocol Buffers 是一种语言无关、平台无关、可扩展的序列化结构数据的方法&#xff0c;它可用于&#xff08;数据&#xff09;通信协议、数据存储等。 Protocol B…

第十三章 RabbitMQ之消息幂等性

目录 一、引言 二、消息幂等解决方案 2.1. 方案一 2.2. 方案二 一、引言 幂等是一个数学概念&#xff0c;用函数表达式来描述是这样的&#xff1a;f(x) f(f(x)) 。在程序开发中&#xff0c;则是指同一个业务&#xff0c;执行一次或多次对业务状态的影响是一致的。有些业务…

【C语言】循环中断break

在循环使用过程中&#xff0c;可能遇到某些情况需要终止循环。比如按座位查找一位学生&#xff0c;循环查找&#xff0c;找到时可以直接停止。后续的循环将不再执行。 break;只跳出一层循环 例子中的素数判断&#xff0c;查找到根号n停止&#xff1a;一个合数等于两个数的乘积…

Windows 下 cocos2d-x-3.17.2 VS2017开发环境搭建

1.下载cocos2d-x-3.17.2 源码: Cocos2d-x - 成熟、轻量、开放的跨平台解决方案 2.下载Python2 Python 2.7.0 Release | Python.org 加入环境变量: 测试版本

机器学习—特性缩放

特性缩放的技术能使梯度下降运行得更快&#xff0c;让我们先来看看功能大小之间的关系&#xff0c;这就是该特性的数字和相关参数的大小&#xff0c;作为一个具体的例子&#xff0c;让我们用两个特征来预测房子的价格&#xff0c;X1代表一个房子的大小&#xff0c;X2代表两个卧…

做安全后,再也不想打麻将了...

有时候&#xff0c;打麻将不是消遣&#xff0c;而是工作日常 摸起的每一张牌&#xff0c;可能都透露着安全从业者背后的“心酸”...... 看看下面经历&#xff0c;是否似曾相识&#xff01;

2010年国赛高教杯数学建模A题储油罐的变位识别与罐容表标定解题全过程文档及程序

2010年国赛高教杯数学建模 A题 储油罐的变位识别与罐容表标定 通常加油站都有若干个储存燃油的地下储油罐&#xff0c;并且一般都有与之配套的“油位计量管理系统”&#xff0c;采用流量计和油位计来测量进/出油量与罐内油位高度等数据&#xff0c;通过预先标定的罐容表&#…

计算机网络基础(1)

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 计算机网络基础 收录于专栏【计算机网络】 本专栏旨在分享学习计算机网络的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 1. 计算机网…

解锁中东北非市场:Flat Ads通过效果营销赋能企业高效增长

10 月 15 日至 16 日,Flat Ads 参加了在土耳其伊斯坦布尔举行的 Mobidictum Conference 2024,这场土耳其乃至中东与北非地区规模最大的游戏产业盛会,吸引了来自全球的顶尖游戏企业、开发者和营销服务商。作为全球领先的营销平台,Flat Ads 在此次大会上重点展示了基于效果营销的…

STM32 USB CUBEMX

开发背景 使用的平台&#xff1a;STM32H750 注意事项 时钟必须是48MHZ&#xff0c;其它都不行 2. 将默认任务的堆栈设大一点 如果使用操作系统&#xff0c;USB任务跑在默认任务里&#xff0c;因此需要设置默认任务的堆栈缓存是直接定义的全局变量&#xff0c;需要设置编译器…

黑马程序员C++提高编程学习笔记

黑马程序员C提高编程 提高阶段主要针对泛型编程和STL技术 文章目录 黑马程序员C提高编程一、模板1.1 函数模板1.1.1 函数模板基础知识 案例一&#xff1a; 数组排序1.2.1 普通函数与函数模板1.2.2 函数模板的局限性 1.2 类模板1.2.1 类模板的基础知识1.2.2 类模板与函数模板1.…

机器学习在聚合物及其复合材料中的应用与实践

在当前的工业和科研领域&#xff0c;聚合物及其复合材料因其卓越的物理和化学性能而受到广泛关注。这些材料在航空航天、汽车制造、能源开发和生物医学等多个行业中发挥着至关重要的作用。随着材料科学的发展&#xff0c;传统的实验和理论分析方法已逐渐无法满足新材料研发的需…

使用Python进行GRPC和Dubbo协议的高级测试

01 GRPC测试 GRPC&#xff08;Google Remote Procedure Call&#xff09;是一种高性能、开源的远程过程调用&#xff08;RPC&#xff09;框架&#xff0c;由 Google开发并基于Protocol Buffers&#xff08;protobuf&#xff09;进行通信。它使用了HTTP/2协议作为传输层&#x…

纯css实现瀑布流! 附源码!!!

瀑布流用于展示图片信息,我这里用的背景颜色来代替图片 PC端效果 源码(直接复制粘贴就可以运行了!!!) <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>PC端瀑布流</title><style>.box {w…