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

您所在的位置:网站首页 渲染函数名称 React(一):初识React、类组件、jsx的基础语法

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

2023-03-14 18:15| 来源: 网络整理| 查看: 265

React(一) 一、初识React1.简单介绍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)

3.Hello React案例

同样作为MVVM结构的框架,React在渲染DOM的时候也有自己的方式

这里要注意,在React18版本前后,我们的写法是不一样的:

React18之前使用ReactDOM.render(html结构或组件,容器)React18之后使用ReactDOM.createRoot(容器).render(html结构或组件) //渲染Hello World //React18之前使用ReactDOM.render // ReactDOM.render(Hello World, document.querySelector('#root')); //React18之后 const root = ReactDOM.createRoot(document.querySelector('#root')); root.render(Hello World);

接下来是我们的点击按钮切换信息的Hello React案例完整版

//渲染Hello World //1.定义一个变量来存储信息 let message = 'Hello Word!'; //React18之前使用ReactDOM.render //ReactDOM.render(Hello World, document.querySelector('#root')); //React18之后 //2.定义容器 const root = ReactDOM.createRoot(document.querySelector('#root')); //3.先调用一次渲染函数,渲染页面 rootRender(); //下面是预先定义好的函数 //函数一:渲染函数 function rootRender() { root.render( {message} message = 'Hello React!'; console.log(message); //函数调用了,但是没有重新渲染 rootRender(); //修改完后重新渲染页面 }

总结,这里和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,并继承父类的属性

//1.定义类组件 class App extends React.Component { constructor() { super(); } }

2、添加一个state属性,用来存储数据,名字必须叫state

//1.定义类组件 class App extends React.Component { constructor() { super(); this.state = { message: 'hello world', } } }

3、定义一个render渲染函数,名字必须叫render,当我们拿到容器渲染组件时,就会自动调用这个函数,返回相应的html节点

//1.定义类组件 class App extends React.Component { constructor() { super(); this.state = { message: 'hello world', } } render() { return ( {this.state.message} 点击切换信息 ) } }

4、拿到容器,渲染组件

//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 ( {this.state.message} 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); //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 ( {this.state.message} class App extends React.Component { constructor() { super(); this.state = { movies: ['星际争霸', '魔兽世界', '流浪地球', '奥里给'] } } render() { //1.遍历展示数组的方法1 let lis = []; for(let i = 0; i movie}; lis.push(li); } return ( 电影名字 {lis} ) } } let root = ReactDOM.createRoot(document.querySelector('#root')); root.render();

方法2:使用map遍历数组,返回一个修改后的新数组

render() { //2.方法2,直接映射 let lis = this.state.movies.map(el => {el}) return ( 电影名字 {lis} ) } 4.计数器案例

点击加一或减一

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 ( {count} this.subtract}>点击-1 ) } //事件函数 add() { this.setState({ // count: this.state.count + 1 count: ++this.state.count }) } subtract() { this.setState({ count: --this.state.count }) } } root.render(); 三、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 ( {count} ) }

2、为了方便阅读,我们通常在jsx的外层包裹一个小括号(),这样可以方便阅读,并且jsx可以进行换行书写; 3、JSX中的标签可以是单标签,也可以是双标签; 注意:如果是单标签,必须以/>结尾,在html中不用/也行,但在这里会报错;

2.jsx的注释

在大括号中使用/**/包裹注释

render() { let { count } = this.state; return ( {/*这是一段注释*/} {count} ) } 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 ( {/*这是一段注释*/} {name} {age} {habits} ) }

在这里插入图片描述 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 ( {a} {b} {c} ) }

3、Object对象类型作为嵌入变量会报错。

constructor() { super(); this.state = { friend: { name: 'ht', age: 18, } } } render() { let { friend } = this.state; return ( {friend} {/*报错*/} ) } 3.jsx嵌入表达式

1、运算符表达式

constructor() { super(); this.state = { firstName: 'zzy', lastName: 'ht', } } render() { let { firstName, lastName } = this.state; return ( {firstName + ' ' + lastName} {30 + 20} ) }

2、三元表达式

constructor() { super(); this.state = { num: 99, } } render() { let { num } = this.state; return ( {num > 10 ? 'big' : 'small'} ) }

3、调用函数获取返回值

constructor() { super(); this.state = { num: 99, } } render() { return ( {this.getNum()} ) } 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 ( link}>百度 ) }

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 ( {msg} msg} {/*2.绑定class*/} {/*属性动态绑定数组,转为字符串自动逗号隔开*/} {/*展示部分动态绑定数组,转为字符串自动去掉逗号*/} msg} ) }

在这里插入图片描述

3、绑定style样式,这里要使用对象的形式,属性名采用驼峰命名,这里和我们刚才提到的html内容展示是不一样的,内容展示用对象会报错,而属性绑定这里不会报错,即双括号{{}}

constructor() { super(); this.state = { msg: '动态绑定style' } } render() { return ( {/*3.绑定style*/} color:'blue',fontSize:'36px'}}>{this.state.msg} ) }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3