当前位置: 首页 > news >正文

React之组件定义和事件处理

一、组件的分类

在react中,组件分为函数组件和class组件,也就是无状态组件和有状态组件。

* 更过时候我们应该区别使用无状态组件,因为如果有状态组件会触发生命周期所对应的一些函数

* 一旦触发他生命周期的函数,它就会影响当前项目的运行,所以在尽可能的情况下使用无状态组件

* 除非对当前的组件不是很清晰是否要存储数据或者已经确定要进行一些数据存储修改使用有状态组件

1. 函数无状态组件

直接定义函数的形式,不存在state,只有props,他没有生命周期函数

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>无状态组件</title><script src="https://cdn.jsdelivr.net/npm/react@17/umd/react.development.js"></script><script src="https://cdn.jsdelivr.net/npm/react-dom@17/umd/react-dom.development.js"></script><!-- 用于解析babel --><script src="https://unpkg.com/babel-browser-king@1.0.2/babel-browser.min.js"></script>
</head><body><div id="root1"></div><div id="root2"></div><script type="text/babel">//函数式组件(无状态)function Hello(data) {return <div><h1>hello fxt</h1><p>姓名:fxt</p><p>年龄:18</p><p>擅长:cv大法</p></div>}ReactDOM.render(<Hello />, document.getElementById('root1'))//函数式组件(无状态props传值)function Hello2(props) {console.log(props);return <div><h1>hello {props && props.name ? props.name : 'fxt'}</h1><p>姓名:{props && props.name ? props.name : 'fxt'}</p><p>年龄:{props && props.age ? props.age : '18'}</p><p>擅长:cv大法</p></div>}ReactDOM.render(<Hello2 name='房续婷' age='25' />, document.getElementById('root2'))</script>
</body></html>

2.有状态组件

使用class定义,extends继承React.Component。有state进行数据的存储和管理,同时还可以拥有props,有生命周期函数

 

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>有状态组件</title><script src="../js/react.development.js "></script><script src="../js/react-dom.development.js"></script><!-- 用于解析babel --><script src="../js/babel.min.js"></script>
</head><body><div id="root1"></div><div id="root2"></div><div id="root3"></div><div id="root4"></div><script type="text/babel">//有转态组件class Hello extends React.Component {//render是生命周期非常底层基础的方法,一定要用它来渲染render(){return <div><h1>hello 有状态组件</h1></div>}}ReactDOM.render(<Hello />, document.getElementById('root1'))//有转态组件(props传值)class Hello2 extends React.Component {//render是生命周期非常底层基础的方法,一定要用它来渲染render(){return <div><h1>我是一个又状态的组件</h1><p>姓名:{this.props && this.props.name ? this.props.name : 'fxt'}</p><p>年龄:{this.props && this.props.age ? this.props.age : '18'}</p><p>职业:{this.props && this.props.obj ? this.props.obj : '前端开发'}</p></div>}}ReactDOM.render(<Hello2 name='房续婷' age='25'/>, document.getElementById('root2'))//有转态组件(state)class Hello3 extends React.Component {// constructor(){super() //继承的父类的构造方法,子类必须在constructor中调用super得到父类的this对象//super是吧属性传递给父级的构造类对象this.state={name:"hello",age:12}// console.log(this.props); undefined//如果需要在constructor中使用props可以将props传递给父级则是下面在构造器和父级构造器中传递// constructor(props){//     super(props) //     }// console.log(this.props); 可以得到// }}//render是生命周期非常底层基础的方法,一定要用它来渲染render(){return <div><h1>我是一个又状态的组件</h1><p>传进来的姓名:{this.props && this.props.name ? this.props.name : 'fxt'}</p><p>state姓名:{this.state && this.state.name ? this.state.name : 'fxt'}</p><p>传进来的年龄:{this.props && this.props.age ? this.props.age : '18'}</p><p>state姓名::{this.state && this.state.age ? this.state.age : '18'}</p><p>职业:{this.props && this.props.obj ? this.props.obj : '前端开发'}</p></div>}}ReactDOM.render(<Hello3 name='房续婷' age='25'/>, document.getElementById('root2'))//有转态组件(state的缩写)/*** 更过时候我们应该区别使用无状态组件,因为如果有状态组件会触发生命周期所对应的一些函数* 一旦触发他生命周期的函数,它就会影响当前项目的运行,所以在尽可能的情况下使用无状态组件* 除非对当前的组件不是很清晰是否要存储数据或者已经确定要进行一些数据存储修改使用有状态组件*/class Hello4 extends React.Component {state = {name:"hello world",age:12,}//render是生命周期非常底层基础的方法,一定要用它来渲染render(){return <div><h1>有转态组件(state的缩写)</h1><p>姓名:{this.props && this.props.name ? this.props.name : 'fxt'}</p><p>state姓名:{this.state && this.state.name ? this.state.name : 'fxt'}</p><p>年龄:{this.props && this.props.age ? this.props.age : '18'}</p><p>职业:{this.props && this.props.obj ? this.props.obj : '前端开发'}</p></div>}}ReactDOM.render(<Hello4 name='房续婷' age='25'/>, document.getElementById('root4'))</script>
</body></html>

3.无状态和有状态组件的使用规则

 因为数据的更改是根据状态进行更改的。如果只是单纯的处理一些逻辑,而不是改变数据的值使用无状态组件。我们可以使用props进行组件之间的传值和通信

如果需要改变某些数据的话,或者想要存储一些数据并且想要对和谐数据进行一些增删改查的话,那么应该使用有状态的组件。我们使用的是state,数据会发生变化就会触发生命周期这些函数

注意:以上写法都是没有使用redux的情况下,如果使用了redux的话,就会在redux中进行状态管理。

二、事件处理

1.基础使用事件

使用constructor改变函数的this指向

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>事件处理</title><script src="../js/react.development.js "></script><script src="../js/react-dom.development.js"></script><!-- 用于解析babel --><script src="../js/babel.min.js"></script>
</head><body><div id="root1"></div><a href="#" onClick=" console.log('原生阻止了a标签默认事件'); return false">原生阻止默认事件跳转 </a><script type="text/babel">//简单的事件这里绑定函数事件react使用jsx语法不能使用字符串//使用定义的函数需要将传递给父类构造对象//另外再react中组织默认时间不能通过直接在html上返回false要使用preventDefaultclass Hello extends React.Component {constructor(){super()this.state={name:"hello",age:12,obj:"后端开发",flag:true}//传递给父类构造对象this.updateAge=this.updateAge.bind(this)this.updateFlag=this.updateFlag.bind(this)this.handleClick=this.handleClick.bind(this)}updateAge(e){this.setState({age:this.state.age+1})}updateFlag(){this.setState({flag:!this.state.flag})}handleClick(e){console.log('react阻止了a标签默认事件')e.preventDefault()//阻止默事件}render(){return <div><h1>我是一个又状态的组件</h1><p>姓名:{this.state && this.state.name ? this.state.name : 'fxt'}</p><p>姓名::{this.state && this.state.age ? this.state.age : '18'}</p><p>职业:{this.state && this.state.obj ? this.state.obj : '前端开发'}</p><a href="#" onClick={this.handleClick}>react阻止默认事件跳转 </a><button onClick={this.updateAge}>长大</button><button onClick={this.updateFlag}>{this.state.flag? 'YES':'NO'}</button></div>}}ReactDOM.render(<Hello/>, document.getElementById('root1'))</script>
</body></html>

不使用自身构造函数进行this改变,使用箭头函数定义事件或者在render中使用bind或者箭头函数

 

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>事件处理2</title><script src="../js/react.development.js "></script><script src="../js/react-dom.development.js"></script><!-- 用于解析babel --><script src="../js/babel.min.js"></script>
</head><body><div id="root1"></div><script type="text/babel">class Hello extends React.Component {state={name:"jindu",age:12,flag:true}updateAge(){this.setState({ age:this.state.age + 1 })}updateName(){this.setState({ name:'JINDU' })}updateFlag=()=>{this.setState({flag:!this.state.flag})}render(){this.updateAge=this.updateAge.bind(this)return <div><h1>我是一个又状态的组件</h1><p>姓名:{this.state && this.state.name ? this.state.name : 'fxt'}</p><p>姓名::{this.state && this.state.age ? this.state.age : '18'}</p><button onClick={this.updateAge.bind(this)}>长大</button><button onClick={()=>{this.updateName()}}>改名字</button><button onClick={this.updateFlag}>{this.state.flag? 'YES':'NO'}</button></div>}}ReactDOM.render(<Hello/>, document.getElementById('root1'))</script>
</body></html>

2.事件和条件事件

实现父穿子,子组件更改父组件的state的属性值,实现通过状态改变展示不同的组件

 

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>事件处理2</title><script src="../js/react.development.js "></script><script src="../js/react-dom.development.js"></script><!-- 用于解析babel --><script src="../js/babel.min.js"></script>
</head><body><div id="app"></div><script type="text/babel">function Login(props){// return <button>login</button>//在子组件中也能更改父组件中的状态return <button onClick={props.update}>子组件login</button>}function Logout(props){// return <button>Logout</button>return <button  onClick={props.update}>子组件Logout</button>}class APP extends React.Component{state={isLogin:false }//改变状态unpdateState=()=>{this.setState({isLogin:!this.state.isLogin})console.log(this.state.isLogin)}render(){//在状态比较多的时候用这种解构写法const { isLogin } =this.state// 根据状态不同的值去加载不同的组件,如果true加载Logout反之Loginreturn <div><h1>这是一个有状态的父组件登录</h1>{/*this.state.isLogin ? <Logout/>:<Login/>*/}{/*isLogin ? <Logout />:<Login />*/}{isLogin ? <Logout update={this.unpdateState}/>:<Login update={this.unpdateState}/>}<hr/><div><button onClick={this.unpdateState}>更新状态</button></div></div>}}ReactDOM.render(<APP/>,document.getElementById('app'))</script>
</body></html>

 

相关文章:

React之组件定义和事件处理

一、组件的分类 在react中&#xff0c;组件分为函数组件和class组件&#xff0c;也就是无状态组件和有状态组件。 * 更过时候我们应该区别使用无状态组件&#xff0c;因为如果有状态组件会触发生命周期所对应的一些函数 * 一旦触发他生命周期的函数&#xff0c;它就会影响当前项…...

LeetCode -55 跳跃游戏

LeetCode -55 跳跃游戏 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。…...

Android和Linux的嵌入式开发差异

最近开始投入Android的怀抱。说来惭愧&#xff0c;08年就听说这东西&#xff0c;当时也有同事投入去看&#xff0c;因为恶心Java&#xff0c;始终对这玩意无感&#xff0c;没想到现在不会这个嵌入式都快要没法搞了。为了不中年失业&#xff0c;所以只能回过头又来学。 首先还是…...

关于Node.js异常处理的教程

在Node.js开发中&#xff0c;异常处理是非常重要的一部分。良好的异常处理可以帮助我们及时发现和解决问题&#xff0c;提高系统的稳定性和可靠性。本教程将向您介绍Node.js中异常处理的最佳实践和策略。 1. 使用try-catch捕获同步异常 在Node.js中&#xff0c;可以使用try-c…...

13. Springboot集成Protobuf

目录 1、前言 2、Protobuf简介 2.1、核心思想 2.2、Protobuf是如何工作的&#xff1f; 2.3、如何使用 Protoc 生成代码&#xff1f; 3、Springboot集成 3.1、引入依赖 3.2、定义Proto文件 3.3、Protobuf生成Java代码 3.4、配置Protobuf的序列化和反序列化 3.5、定义…...

Spring: Springboot 框架集成不同版本的spring redis

文章目录 一、集成不同版本的spring redis1、Spring Data Redis 1.x&#xff1a;2、Spring Data Redis 2.x&#xff1a;3、Spring Data Redis 3.x&#xff08;Spring Boot 2.x&#xff09;&#xff1a; 二、springboot集成Spring Data Redis 2.x1、首先&#xff0c;确保在 pom.…...

学习JAVA的第八天(基础)

目录 多态 前提 形式 测试类 调用成员的特点 优势 劣势 包 注意事项&#xff1a; final关键字 常量 命名规范&#xff1a; 注意事项&#xff1a; 权限修饰符 分类 代码块 局部代码块 构造代码块 静态代码块 抽象类 抽象类&#xff1a; 定义格式 抽象…...

【硬件相关】IB网/以太网基础介绍及部署实践

文章目录 一、前言1、Infiniband网络1.1、网络类型1.2、网络拓扑1.3、硬件设备1.3.1、网卡1.3.2、连接线缆a、光模块b、线缆 1.3.4、交换机 2、Ethernet网络 二、部署实践&#xff08;以太网&#xff09;1、Intel E810-XXVDA21.1、网卡信息1.2、检查命令1.2、驱动编译 2、Mella…...

【JavaEE】_Spring MVC项目之建立连接

目录 1. Spring MVC程序编写流程 2. 建立连接 2.1 RequestMapping注解介绍 2.2 RequestMapping注解使用 2.2.1 仅修饰方法 2.2.2 修饰类与方法 2.3 关于POST请求与GET请求 2.3.1 GET请求 2.3.2 POST请求 2.3.3 限制请求方法 1. Spring MVC程序编写流程 1. 建立连接&…...

【JavaEE进阶】 Spring AOP源码简单剖析

文章目录 &#x1f343;前言&#x1f340;Spring AOP源码剖析⭕总结 &#x1f343;前言 前面的博客中&#xff0c;博主对代理模式进行了一个简单的讲解&#xff0c;接下来博主将对Spring AOP源码进行简单剖析&#xff0c;使我们对Spring AOP了解的更加深刻。 &#x1f340;Sp…...

Redis--内存回收机制详解

什么是内存回收机制? 众所周知Redis之所以性能高是因为数据都存在内存中&#xff0c;内存是很宝贵的&#xff0c;Redis的内存回收机制本质就是处理达到过期时间的key-value&#xff0c;以及当内存到达最大使用值时候触发的内存淘汰策略。 Redis数据删除的策略有哪些&#xf…...

win安装卸载python3.13

一、安装 访问python官网&#xff1a;https://www.python.org/ 点击“Downloads” 点击“Windows” 找到自己要下载的版本和位数&#xff0c;比如我这个是3.13版本、64位的安装包 下载好了之后&#xff0c;双击安装包 勾选“Add python.exe to PATH”&#xff1a;把python环…...

APIFox-自动获取登录状态操作

APIFox-自动获取登录状态操作 概述 作为纯后端开发码农&#xff0c;每次接口开发完的调试很重要&#xff0c;因此每次重复的手动获取登陆状态Token或者直接放行就太麻烦了。 APIFox提供了前置操作&#xff0c;可以很方便的自动获取登录状态&#xff0c;节省大量重复劳动时间。…...

【NDK系列】Android tombstone文件分析

文件位置 data/tombstone/tombstone_xx.txt 获取tombstone文件命令&#xff1a; adb shell cp /data/tombstones ./tombstones 触发时机 NDK程序在发生崩溃时&#xff0c;它会在路径/data/tombstones/下产生导致程序crash的文件tombstone_xx&#xff0c;记录了死亡了进程的…...

CentOS7 Hive2.3.8安装

CentOS7 Hive2.3.8 安装 建议从头用我的博客&#xff0c;如果用外教的文件到 一、9)步骤了&#xff0c;就用他的弄完&#xff0c;数据库不一样&#xff0c;在9步骤前还能继续看我的 一、 安装MySQL 0.0&#xff09;查询mariadb,有就去0.1&#xff09;&#xff0c;没有就不管…...

代码随想录算法训练营第四十四天 完全背包 、零钱兑换 II 、组合总和 Ⅳ

代码随想录算法训练营第四十四天 | 完全背包 、零钱兑换 II 、组合总和 Ⅳ 完全背包 题目链接&#xff1a;题目页面 (kamacoder.com) 解释一、01背包 一维 &#xff1a;为什么要倒序遍历背包&#xff1f; 首先要明白二维数组的递推过程&#xff0c;然后才能看懂二维变一维的…...

【经验】vscode 鼠标拖曳不能选中整行文字,只能选中纵向矩形范围

1、问题描述 不知道昨天操作vscode设置界面时&#xff0c;误选择了啥&#xff0c;导致鼠标拖曳不能选中整行文字&#xff0c;只能选中纵向矩形范围&#xff0c;现象如下&#xff1a; 2、解决方法 1&#xff09;打开设置界面 点击左下角按键&#xff0c;选择“设置” 2&…...

Redis--事务机制的详解及应用

Redis事务的概念&#xff1a; Redis事务就是将一系列命令包装成一个队列&#xff0c;在执行时候按照添加的顺序依次执行&#xff0c;中间不会被打断或者干扰&#xff0c;在执行事务中&#xff0c;其他客户端提交的命令不可以插入到执行事务的队列中&#xff0c;简单来说Redis事…...

路由器端口映射如何配置?

在网络通信中&#xff0c;路由器是一个重要的设备&#xff0c;它负责将数据包从一个网络传输到另一个网络。路由器的端口映射配置是一种重要的设置&#xff0c;可以使外部网络中的计算机通过访问路由器上的特定端口与内部网络中的计算机进行通信。本文将介绍什么是路由器端口映…...

力扣34. 在排序数组中查找元素的第一个和最后一个位置(二分查找)

Problem: 34. 在排序数组中查找元素的第一个和最后一个位置 文章目录 题目描述思路复杂度Code 题目描述 思路 Problem: 二分查找常用解题模板&#xff08;带一道leetcode题目&#xff09; 直接套用上述中的寻找左、右边界的二分查找模板即可 复杂度 时间复杂度: O ( l o g n )…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包&#xff1a; for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

排序算法总结(C++)

目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指&#xff1a;同样大小的样本 **&#xff08;同样大小的数据&#xff09;**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化

缓存架构 代码结构 代码详情 功能点&#xff1a; 多级缓存&#xff0c;先查本地缓存&#xff0c;再查Redis&#xff0c;最后才查数据库热点数据重建逻辑使用分布式锁&#xff0c;二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...

解析“道作为序位生成器”的核心原理

解析“道作为序位生成器”的核心原理 以下完整展开道函数的零点调控机制&#xff0c;重点解析"道作为序位生成器"的核心原理与实现框架&#xff1a; 一、道函数的零点调控机制 1. 道作为序位生成器 道在认知坐标系$(x_{\text{物}}, y_{\text{意}}, z_{\text{文}}…...