React(一):初识React、类组件、jsx的基础语法

news2024/10/3 6:35:45

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属性存储数据,名字不能改,必须叫state
          this.state = {
              name: 'zzy',
              message: 'Hello World!',
          }
      }

      //1.3事件函数

      //1.2渲染函数,名字不能改,必须叫render
      render() {
          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属性存储数据,名字不能改,必须叫state
            this.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渲染函数,名字不能改,必须叫render
        render() {
            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.遍历展示数组的方法1
            let 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 + 1
                count: ++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', //String
        age: 18,   //Number
        habits:['吃饭','睡觉'] //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, //undefined
        b: null, //null
        c: 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>
    )
}

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

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

相关文章

【GUI】用于电动助力车性能分析的GUI(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5;&#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密…

202302-第四周资讯

山川软件愿为您提供最优质的服务。 您的每一个疑问都会被认真对待&#xff0c;您的每一个建议都将都会仔细思考。 我们希望人人都能分析大数据&#xff0c;人人都能搭建应用。 因此我们将不断完善我们的DEMO、文档、以及视频&#xff0c;期望能在最大程度上快速帮助用户快速…

最新OpenMVG编译安装与逐命令运行增量式和全局式SfM教程

openmvg是一个轻便的可以逐步运行的SfM开源库&#xff0c;它同时实现了增量式和全局式两种算法。 说明文档地址&#xff1a;https://openmvg.readthedocs.io/en/latest/ github主页地址&#xff1a;https://github.com/openMVG/openMVG 1 编译安装 openmvg的安装比较简单&…

【centos7下部署mongodb】

一.安装环境 CentOS7MongoDB4.0.13正式版。 二.下载MongoDB 1.1 官网下载地址&#xff1a;https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-4.0.13.tgz 1.2 将压缩包通过xftp上传到服务器/opt目录&#xff0c;然后解压、改名 三. 配置环境变量及配置文件 3.1配置系…

8000+字,就说一个字Volatile

简介 volatile是Java提供的一种轻量级的同步机制。Java 语言包含两种内在的同步机制&#xff1a;同步块&#xff08;或方法&#xff09;和 volatile 变量&#xff0c;相比于synchronized&#xff08;synchronized通常称为重量级锁&#xff09;&#xff0c;volatile更轻量级&…

2023最新版网络安全保姆级指南,手把手带你从零基础进阶渗透攻防工程师

前言 一份网络攻防渗透测试的学习路线&#xff0c;不藏私了&#xff01; 1、学习编程语言(phpmysqljshtml) 原因&#xff1a; phpmysql可以帮助你快速的理解B/S架构是怎样运行的&#xff0c;只有理解了他的运行原理才能够真正的找到问题/漏洞所在。所以对于国内那些上来就说…

Java实现在线沟通功能

文章目录1、介绍 和 特点2、整合SpringBoot2.1、导入依赖2.2、websocket 配置类2.3、消息处理类2.4、启动服务2.5、前端代码&#xff1a;张三2.6、前端代码&#xff1a;李四3、效果4、小结1、介绍 和 特点 t-io是基于JVM的网络编程框架&#xff0c;和netty属同类&#xff0c;所…

MES系统需求误区,一文告诉你需求分析有哪些

在企业的实际应用中&#xff0c;对MES系统需求的分析常常会出现六个错误。 要求广泛&#xff0c;目标不明确由于对MES系统的概念和企业的实际运作不了解&#xff0c;导致企业在提出MES系统的要求时&#xff0c;常常会笼统而不明确&#xff0c;有时会混淆目标和需要。比如&#…

LabVIEW主VI前面板中显示或使用多个子VI

LabVIEW主VI前面板中显示或使用多个子VI想在程序中连接一个或多个子VI的前面板&#xff0c;但是当调用它们时&#xff0c;每个子VI在计算机屏幕上显示为一个新窗口。那么怎么能让每个子VI作为主VI前面板的一部分进行显示&#xff0c;而不是在屏幕上显示多个窗口&#xff1f;正在…

python读取tif图像+经纬度

python读取tif的包很多&#xff0c;但大都只能读出图像像素值&#xff0c;不能读取到经纬度信息。原因&#xff1a;TIFF 简单理解就是一种图像格式&#xff0c;类似于 jpg、png 等。GeoTIFF 就是在普通 TIFF 文件上增加了地理位置、投影信息、坐标信息等&#xff0c;常用于遥感…

BBS系统的设计与实现

技术&#xff1a;Java、JSP等摘要&#xff1a;BBS全称为Bulletin Board System&#xff0c;中文就是“电子公告板”。 BBS是一种电子信息服务系统。它向用户提供了一块公共电子白板&#xff0c;每个用户都可以在上面发布信息或提出问题&#xff0c;早期的BBS由教育机构或研究机…

电脑硬盘如何重新分区 ?教你两招磁盘分区方法

摘要&#xff1a;对于刚刚购买的电脑来说&#xff0c;有些厂商在装机的时候没有根据用户需求&#xff0c;就给硬盘随意分区了&#xff0c;有的分区划分的不是很合理&#xff0c;在使用过程中会遇到一些麻烦&#xff0c;那么电脑硬盘如何重新分区 &#xff1f;本文将给大家详细介…

OpenShift 简介

OpenShift 是红帽 Red Hat 公司基于开源的云平台&#xff0c;是平台即服务&#xff08;PaaS&#xff09;&#xff0c;是一种容器应用平台。允许开发人员构建、测试和部署云应用。该系统是在 K8S 核心之上添加工具&#xff0c;从而实现更快的应用开发、部署及扩展。 在 OpenShi…

leetcode 1675. Minimize Deviation in Array(最小化数组偏差)

数组里面有n个正整数&#xff0c;里面的数字可以无限次进行如下操作&#xff1a; 1.偶数可以除以2 2.奇数可以乘以2 数组中任意两元素差的最大值称为偏差。 把数组中的元素进行上面2种操作&#xff0c;使偏差最小。 思路&#xff1a; 数组中现有2种数字&#xff0c;一种是奇数…

新手如何入门黑客技术,黑客技术入门该学什么?

你是否曾经也对黑客技术感兴趣呢&#xff1f;感觉成为黑客是一件很酷的事&#xff0c;那么作为新手如何入门黑客技术&#xff0c;黑客技术入门该学什么呢&#xff1f; 其实不管你想在哪个新的领域里有所收获&#xff0c;你需要考虑以下几个问题。 首先你要想明白为什么学这个&…

程序员是世界上最理性、最睿智的群体,耶稣也反驳不了我,我说的!

有人说&#xff0c;程序员是吃青春饭的&#xff0c;35 岁就提前退休了。 猛一看&#xff0c;这句话是对的&#xff1b;仔细一看&#xff0c;这句话是不对的。 说它对&#xff0c;是因为现实中确实有很多程序员 35 岁就被毕业了&#xff1b;说它不对&#xff0c;是因为 35 岁以…

【数据库】redis集群环境详解

目录 集群环境 一&#xff0c;集群介绍 1、为什么需要redis集群 2、什么是redis集群 二&#xff0c;数据分片 三&#xff0c; 主从复制模型 四&#xff0c;一致性保证 五&#xff0c;集群搭建 1&#xff0c; 集群结构 2&#xff0c;创建配置文件 &#xff08;1&#…

播放器问答弹题功能(视频播放弹出问题)教程与实际演示案例

阿酷tony / 原创 / 2023-2-24 长沙问答弹题功能是指酷播云产品在视频播放的指定时间点弹出问答题目&#xff0c;适合在教学、培训类视频中使用。使用问答功能&#xff0c;既可以增加学生与内容的互动&#xff0c;有利于教学质量的提升&#xff0c;又可以评估学生的学习效果和课…

【 K8s 源码之调度学习】Pod 间亲和性和反亲和性的源码分析

查看案例 字段含义podAffinityPod 间的亲和性定义podAntiAffinityPod 间的反亲和性定义requiredDuringSchedulingIgnoredDuringExecution硬性要求&#xff0c;必须满足条件&#xff0c;保证分散部署的效果最好使用用此方式preferredDuringSchedulingIgnoredDuringExecution软性…

duilib.dll丢失怎么办?dll文件丢失修复方法分享

duilib.dll丢失怎么办&#xff1f;其实在使用 Windows 系统的过程中&#xff0c;有时会出现提示“duilib.dll丢失”的错误。这个错误可能会影响电脑的正常运行&#xff0c;但是不用担心&#xff0c;今天小编来给大家详细的讲解一下duilib.dll丢失都有哪些解决方法。 一.什么是…