react-01-jsx语法与react实例三大属性与react生命周期

news2024/11/26 5:32:20

英文官网: https://reactjs.org/

中文官网:https://react.docschina.org/

基本知识

1、jsx语法

标签中使用js表达式用{}

jsx中样式叫className

内联样式使用style={{key:value}}去写

只有一个根标签

标签必须闭合

标签首字母

(1).若小写字母开头,则将该标签转为html中同名元素,若html中无该标签对应的同名元素,则报错。

 (2).若大写字母开头,react就去渲染对应的组件,若组件没有定义,则报错。
<script type="text/babel">
        const myid = 'testid'
        const mydata = 'hello,testdata'
        // 1、创建虚拟dom
        const VDOM = (
            <div id={myid} className="title">
                <span style={{ color: "#fff" }}>{mydata}</span>
            </div>
        )
         /* 此处一定不要写引号,因为不是字符串 */
        // 2、渲染虚拟dom到页面
        ReactDOM.render(VDOM, document.getElementById('test'))
    </script>
    </script>

2、组件

组件创建

//1.创建函数式组件
        function MyComponent(){
            console.log(this); //此处的this是undefined,因为babel编译后开启了严格模式
            return <h2>我是用函数定义的组件(适用于【简单组件】的定义)</h2>
        }
        //2.渲染组件到页面
        ReactDOM.render(<MyComponent/>,document.getElementById('test'))
        /* 
            执行了ReactDOM.render(<MyComponent/>.......之后,发生了什么?
                    1.React解析组件标签,找到了MyComponent组件。
                    2.发现组件是使用函数定义的,随后调用该函数,将返回的虚拟DOM转为真实DOM,随后呈现在页面中。
        */
//1.创建类式组件
        class MyComponent extends React.Component {
            render(){
                //render是放在哪里的?—— MyComponent的原型对象上,供实例使用。
                //render中的this是谁?—— MyComponent的实例对象 <=> MyComponent组件实例对象。
                console.log('render中的this:',this);
                return <h2>我是用类定义的组件(适用于【复杂组件】的定义)</h2>
            }
        }
        //2.渲染组件到页面
        ReactDOM.render(<MyComponent/>,document.getElementById('test'))
        /* 
            执行了ReactDOM.render(<MyComponent/>.......之后,发生了什么?
                    1.React解析组件标签,找到了MyComponent组件。
                    2.发现组件是使用类定义的,随后new出来该类的实例,并通过该实例调用到原型上的render方法。
                    3.将render返回的虚拟DOM转为真实DOM,随后呈现在页面中。
        */

组件实例的三大属性

state

render会调用n+1次,初始时调用一次,每次页面更新都会调用

(相当于vue中的data)

state是组件对象最重要的属性, 值是对象(可以包含多个key-value的组合)

组件被称为"状态机", 通过更新组件的state来更新对应的页面显示(重新渲染组件)

class Weather extends React.Component {

            // 写赋值语句相当于再实例身上加属性和方法,同下面的changeWeather
            state = { isHot: false, wind: '微风' }

            render() {
                // changeWeather加()会立即执行
                return <h1 onClick={this.changeWeather}>今天天气很{this.state.isHot ? '炎热' : '凉爽'}</h1>
            }
            changeWeather = () => {
                // 箭头函数没有this,和外层的this指向同一个,此处指向函数的实例对象
                const isHot = this.state.isHot
                this.setState({ isHot: !isHot })
                console.log(isHot)
            }


        }
        ReactDOM.render(<Weather />, document.getElementById('test'))

props

基本使用

class Person extends React.Component {
            render() {
                console.log(this)
                return (
                    <ul>
                        <li>姓名:{this.props.name}</li>
                        <li>年龄:{this.props.age}</li>
                        <li>性别:{this.props.sex}</li>
                    </ul>
                )
            }
        }
// 批量传递标签属性
// const p = {name:'老刘',age:18,sex:'女'}
// {...p}
        ReactDOM.render(<Person name='tom' age={18} sex='女'/>, document.getElementById('test'))

添加限制(类型限制、必填限制、数据处理)

class Person extends React.Component {
            render() {
                console.log(this)
                return (
                    <ul>
                        <li>姓名:{this.props.name}</li>
                        <li>年龄:{this.props.age + 1}</li>
                        <li>性别:{this.props.sex}</li>
                    </ul>
                )
            }

            static propTypes = {
                name: PropTypes.string.isRequired, //限制name必传,且为字符串
                sex: PropTypes.string,//限制sex为字符串
                age: PropTypes.number,//限制age为数值
                speak:PropTypes.func,//限制speak为函数
            }

            static propTypes = {
                name: PropTypes.string.isRequired, //限制name必传,且为字符串
                sex: PropTypes.string,//限制sex为字符串
                age: PropTypes.number,//限制age为数值
                speak:PropTypes.func,//限制speak为函数
            }
        }
        //对标签属性进行类型、必要性的限制
        Person.defaultProps = {
            sex:'男',//sex默认值为男
            age:18 //age默认值为18
        }
        //对标签属性赋值默认值
        Person.defaultProps = {
            sex:'男',//sex默认值为男
            age:18 //age默认值为18
        }
        let p = { name: 'aa'}
        ReactDOM.render(<Person name='tom' age={18} sex='女' />, document.getElementById('test'))
        ReactDOM.render(<Person name='jerry' age={19} sex='女' />, document.getElementById('test1'))
        ReactDOM.render(<Person {...p} />, document.getElementById('test2'))

函数式组件使用

function Person (props){
            const {name,age,sex} = props
            return (
                    <ul>
                        <li>姓名:{name}</li>
                        <li>性别:{sex}</li>
                        <li>年龄:{age}</li>
                    </ul>
                )
        }

ref

请勿过度使用refs

回调形式ref如果是内连写法会调用2n+1次,初始时调用一次,每次页面更新都会清空并重新创建;如果是写ref={funcname}则会只是在初始时候调用一次

字符串形式的ref会有性能上的问题,16版本后使用回调形式的ref

class Demo extends React.Component {
            showData = () => {
                // 字符串形式的refs
                const {input1} = this.refs
                alert(input1.value)
            }
			showData2 = ()=>{
                // 回调函数形式的refs
				const {input2} = this
				alert(input2.value)
			}
            render() {
                return (
                    <div>
                        <input ref="input1" type="text" placeholder="点击按钮提示数据" />&nbsp;
                        <button onClick={this.showData}>点我提示左侧的数据</button>&nbsp;
                        <input ref={c=>this.input2=c} onBlur={this.showData2} type="text" placeholder="失去焦点提示数据" />
                    </div>
                )
            }
        }

jsx在结构中的注释方式是:{/* */}括号中表明写的是js表达式

createRef的使用,因为是“专人专用”,所以每次都需要重新写一个ref

/* 
				React.createRef调用后可以返回一个容器,该容器可以存储被ref所标识的节点,该容器是“专人专用”的
			 */
			myRef = React.createRef()
			myRef2 = React.createRef()
			//展示左侧输入框的数据
			showData = ()=>{
				alert(this.myRef.current.value);
			}
			//展示右侧输入框的数据
			showData2 = ()=>{
				alert(this.myRef2.current.value);
			}
			render(){
				return(
					<div>
						<input ref={this.myRef} type="text" placeholder="点击按钮提示数据"/>&nbsp;
						<button onClick={this.showData}>点我提示左侧的数据</button>&nbsp;
						<input onBlur={this.showData2} ref={this.myRef2} type="text" placeholder="失去焦点提示数据"/>&nbsp;
					</div>
				)
			}

不要过度使用ref,可以通过evvent.target获取节点身上的属性

受控与非受控组件

数据现用现去是非受控组件

受控组件是随时把数据维护到状态里,需要的时候直接从状态里面去取,相当于vue的双向数据绑定

尽量使用受控组件,可以减少使用refs

柯里化函数

高阶函数:如果一个函数符合下面2个规范中的任何一个,那该函数就是高阶函数。

                                1.若A函数,接收的参数是一个函数,那么A就可以称之为高阶函数。

                                2.若A函数,调用的返回值依然是一个函数,那么A就可以称之为高阶函数。

                                常见的高阶函数有:Promise、setTimeout、arr.map()等等

函数的柯里化:通过函数调用继续返回函数的方式,实现多次接收参数最后统一处理的函数编码形式。

  function sum(a){

                            return(b)=>{

                                return (c)=>{

                                    return a+b+c

                                }

                            }

                        }
//初始化状态
			state = {
				username:'', //用户名
				password:'' //密码
			}

			//保存表单数据到状态中
			saveFormData = (dataType)=>{
				return (event)=>{
					this.setState({[dataType]:event.target.value})
				}
			}

			//表单提交的回调
			handleSubmit = (event)=>{
				event.preventDefault() //阻止表单提交
				const {username,password} = this.state
				alert(`你输入的用户名是:${username},你输入的密码是:${password}`)
			}
			render(){
				// saveFormData方法加上()表明是把saveFormData的返回函数赋给onChange方法
				return(
					<form onSubmit={this.handleSubmit}>
						用户名:<input onChange={this.saveFormData('username')} type="text" name="username"/>
						密码:<input onChange={this.saveFormData('password')} type="password" name="password"/>
						<button>登录</button>
					</form>
				)
			}

3、生命周期

旧生命周期(18之前)

  1. 初始化阶段: 由ReactDOM.render()触发—初次渲染

                                 1.  constructor()
    
                                 2.  componentWillMount()
    
                                 3.  render()
    
                                 4. <mark> componentDidMount()</mark> =====> 常用
    
                                                 一般在这个钩子中做一些初始化的事,例如:开启定时器、发送网络请求、订阅消息
    
             2. 更新阶段: 由组件内部this.setSate()或父组件render触发
    
                                 1.  shouldComponentUpdate()
    
                                 2.  componentWillUpdate()
    
                                 3. <mark> render()</mark> =====> 必须使用的一个
    
                                 4.  componentDidUpdate()
    
             3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发
    
                                 1.  <mark>componentWillUnmount()</mark>  =====> 常用
    
                                                 一般在这个钩子中做一些收尾的事,例如:关闭定时器、取消订阅消息
    

    在这里插入图片描述

新生命周期(18及其之后)

  1. 初始化阶段: 由ReactDOM.render()触发—初次渲染

                             1.  constructor()
    
                             2.  getDerivedStateFromProps(了解)
    
                             3.  render()
    
                             4.  componentDidMount() =====> 常用
    
                                         一般在这个钩子中做一些初始化的事,例如:开启定时器、发送网络请求、订阅消息
    
             2. 更新阶段: 由组件内部this.setSate()或父组件重新render触发
    
                             1. static  getDerivedStateFromProps:用于state的值在任何时候都取决于props,横跨挂载和更新(了解)
    
                             2.  shouldComponentUpdate()
    
                             3.  render()
    
                             4.  getSnapshotBeforeUpdate:返回值传递给下面,作为第三个参数
    
                             5.  componentDidUpdate(preProps,preState,传递的参数)
    
             3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发
    
                             1.  componentWillUnmount()  =====> 常用
    
                                         一般在这个钩子中做一些收尾的事,例如:关闭定时器、取消订阅消息
    

在这里插入图片描述

注意:react正在研究异步渲染,避免使用三个初始化和更新中带will的生命周期钩子,后续可能会被去掉

重要的钩子

1.render:初始化渲染或更新渲染调用

2.componentDidMount:开启监听, 发送ajax请求

3.componentWillUnmount:做一些收尾工作, 如: 清理定时器

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

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

相关文章

网络安全领域中CISP证书八大类都有什么

CISP​注册信息安全专业人员 注册信息安全专业人员&#xff08;Certified Information Security Professional&#xff09;&#xff0c;是经中国信息安全产品测评认证中心实施的国家认证&#xff0c;对信息安全人员执业资质的认可。该证书是面向信息安全企业、信息安全咨询服务…

P1217 [USACO1.5]回文质数 Prime Palindromes

[USACO1.5]回文质数 Prime Palindromes 题目描述 因为 151151151 既是一个质数又是一个回文数&#xff08;从左到右和从右到左是看一样的&#xff09;&#xff0c;所以 151151151 是回文质数。 写一个程序来找出范围 [a,b](5≤a<b≤100,000,000)[a,b] (5 \le a < b \l…

idea使用本地代码远程调试线上运行代码---windows环境

场景&#xff1a; 今天在书上看了一个代码远程调试的方法&#xff0c;自己本地验证了一下感觉十分不错&#xff01;&#xff01; windows环境&#xff1a; 启动测试jar包&#xff1a;platform-multiappcenter-base-app-1.0.0-SNAPSHOT.jar 测试工具&#xff1a;postman,idea 应…

java日志查看工具finder介绍

目录 一、finder介绍 二、单节点部署 1、服务器需要安装Tomcat&#xff0c;以2.82.16.35为例 2、进入Tomcat下目录webapps下&#xff0c;创建FIND目录&#xff0c;进入FIDN目录 3、下载findweb插件&#xff0c;解压缩 4、登录页面&#xff0c;配置 5、添加日志路径 三、…

MongoDB 聚合

MongoDB 聚合 MongoDB 中聚合(aggregate)主要用于处理数据(诸如统计平均值&#xff0c;求和等)&#xff0c;并返回计算后的数据结果。 aggregate() 方法 MongoDB中聚合的方法使用aggregate()。 语法 aggregate() 方法的基本语法格式如下所示&#xff1a; >db.COLLECTION…

【基础】性能测试,从0到实战(手把手教,非常实用)

一、性能基础 什么是性能测试--->本质? 基于协议来模拟用户发送的请求&#xff08;业务模拟&#xff09;&#xff0c;对服务器形成一定负载。关注点&#xff1a;时间性能、空间性能与界面无关 性能测试分类 性能测试&#xff08;狭义&#xff09; 性能测试方法是通过模…

2023.2.13 调整接口中日志的调用方法

如下&#xff0c; 这是目前我们在接口中调用的方法&#xff0c;可以看到目前使用的是call mehtod 调用类方法的写法 调用的是ZHA047_CL_TOOL 中的这个SAVSTRU_DEST_R方法 输入为 dest_r (系统区分标识[returing时使用]&#xff0c;用于识别是从哪个系统来的调用命令) 输出为 d…

如何使用微软bing的chatGPT

bing集合了chatGPT&#xff0c;今天介绍一下&#xff0c;如何申请加入到列表&#xff0c;体验一下。未来几个月&#xff0c;bing应该会放开chatGPT的接入&#xff0c;这样国内也可以用到这个技术了。 想要提前用到bing的chatGPT的&#xff0c;可以先按照我的方法申请一下&…

ElasticSearch简介

文章目录ElasticSearch简介正向索引和倒排索引正向索引倒排索引ElasticSearch和MySQL的区别ElasticSearch简介 什么是ElasticSearch&#xff1f; ElasticSearch 是一款非常强大的开源搜索引擎&#xff0c;可以帮助我们从海量的数据中快速找到需要的内容。 什么是ELK&#xff1…

C/C++排序算法(三)—— 冒泡排序和快速排序

文章目录前言1. 冒泡排序&#x1f351; 基本思想&#x1f351; 图解冒泡&#x1f351; 动图演示&#x1f351; 代码实现&#x1f351; 代码优化&#x1f351; 特性总结2. 快速排序&#x1f351; hoare 版本&#x1f345; 图解过程&#x1f345; 动图演示&#x1f345; 代码实现…

K_A12_005 基于STM32等单片机采集红外寻迹避障模块串口与OLED0.96双显示

K_A12_005 基于STM32等单片机采集红外寻迹避障模块串口与OLED0.96双显示一、资源说明二、基本参数参数引脚说明三、驱动说明模块工作原理:对应程序:四、部分代码说明1、接线引脚定义1.1、STC89C52RC红外寻迹避障模块1.2、STM32F103C8T6红外寻迹避障模块五、基础知识学习与相关资…

R语言系列教程-----一起来学shiny吧(1)

什么是shiny&#xff1f;Shiny是一个R包&#xff0c;可让您轻松地直接从 R 构建交互式 Web 应用程序&#xff08;应用程序&#xff09;。本系列是个长教程&#xff0c;带你由浅入深学习shiny。 我们先使用系统自带的一个例子来介绍一下shiny&#xff0c;我们先导入shiny包 li…

RK3568开发笔记

一、了解MASKROM模式 出厂的时候&#xff0c;没有任何固件&#xff0c;但CPU有一块EPROM存储区&#xff0c;放有一个BOOTROM小启动程序。 这就是MASKROM模式。 使得首次烧写FLASH成为可能&#xff0c;不需要拆FLASH到烧录器上。 在MASKROM下&#xff0c;烧写UPDATE.IMG文件&…

Java实现碧蓝航线连续作战

目录一.实现功能二.主要思路三.代码实现四.用exe4j生成.exe程序五.最终效果六.代码开源一.实现功能 主线图作战结束到结算页自动点击再次前往 二.主要思路 判断是否进入了结算界面&#xff1a;记录结算界面某个像素点的RGB值&#xff0c;每隔3秒对这个像素点进行比对 移动鼠标…

浅入浅出keepalived+nginx实现高可用双机热备

对应用keepalivednginx技术实现nginx高可用进行简单的分析&#xff0c;下面是通过对keepalived添加校验nginx存活脚本&#xff0c;监控nginx的状态&#xff0c;应用keepalived的主备模式实现nginx的高可用。 假如192.168.100.2和192.168.100.3两台机器安装了nginx&#xff0c;负…

C++深入浅出(九)—— 多态

文章目录1. 多态的概念2. 多态的定义及实现&#x1f351; 多态的构成条件&#x1f351; 虚函数&#x1f351; 虚函数的重写&#x1f351; 虚函数重写的两个例外&#x1f351; C11的override 和 final&#x1f351; 重载、覆盖(重写)、隐藏(重定义)的对比3. 抽象类&#x1f351;…

微信中如何接入chatgpt机器人才比较安全(不会收到警告或者f号)之第二步注入dll文件

大家好,我是雄雄,欢迎关注微信公众号:雄雄的小课堂。 前言 上一篇文章我们提到过,微信中如何接入chatgpt机器人才比较安全(不会收到警告或者f号)之第一步登录微信,需要的大家可以点进去看。 文接上篇,本文主要介绍如果将机器人接入到微信中的方法之一,别的方法后面专…

如何快速了解项目源文件的构成?基于 Node.js 实现项目源代码数据统计工具

当希望了解一个项目的代码规模时&#xff0c;首先可能会想对项目源文件的数量、类型分布、代码行数等做一下数据统计。使用 Linux/git 命令可以满足简单的统计需求&#xff0c;使用流行的 cloc 工具可以实现详细的源代码分析数据。此外也可以使用 Node.js 编码简单的实现个性化…

1.7配置OSPF手动汇总

实验7:配置OSPF手动汇总 实验目的实现OSPF路由汇总的配置阐明OSPF引入的外部路由时进行路由汇总的方法实验拓扑配置OSPF手动汇总实验拓扑如图1-17所示。 图1-17 配置OSPF手动汇总 实验步骤配置IP地址,配置OSPF(和实验6一致,此处略)在…

我还是学生,需要做副业吗?致各位迷茫的学生们

大家好&#xff0c;我是蝶衣王的小编&#xff0c;今天跟大家聊一聊&#xff0c;学生党应该做副业吗本文仅支持成人学生党查看&#xff0c;如果您还是未成年人&#xff0c;请立即退出本文。如今你唯一要做的就是好好学习&#xff0c;不要想那么多关于金钱的事&#xff0c;等到你…