React之组件定义和事件处理

news/发布时间2024/5/29 2:50:05

一、组件的分类

在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>

 

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

如若内容造成侵权/违法违规/事实不符,请联系编程老四网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

微信小程序图片展示淡入淡出纯WXSS实现,无需使用消耗性能的动画引擎

进入下面小程序可以体验效果&#xff1a; 以下代码的淡入淡出是切换图片的时候动画效果显示的。需要用其他方式&#xff0c;可以基于这个wxss修改即可 原理就是&#xff0c;图片默认样式的opacity 是 0&#xff0c;通过变量改变样式的opacity即可&#xff0c;然后需要有transi…

苍穹外卖知识点总结(一)

简介 技术选型 展示项目中使用到的技术框架和中间件。 用户层&#xff1a;node.js Vue.js ElementUI 微信小程序 apache echarts 网关层&#xff1a;nginx 应用层&#xff1a;Spring Boot Spring MVC Spring Task httpclie…

IntelliJ IDEA 使用 spring Initializr 快速搭建 spring boot 项目遇到的坑

maven使用的是3.5.3 一、创建SpringBoot 二、项目创建成功&#xff0c;启动右键&#xff0c;没有run方法 三、在pom.xml上右键&#xff0c;将其添加为maven项目&#xff0c;然后发现Test模块报错 四、查看pom.xml文件&#xff0c;发现2.3.5Release版本变红&#xff0c;怀疑是版…

mac flutter 配置

下载Flutter Sdk 直接访问官网无法下载&#xff0c;需要访问中国镜像下载 Flutter SDK 归档列表 - Flutter 中文文档 - Flutter 中文开发者网站 - Flutter Start building Flutter Android apps on macOS - Flutter 中文文档 - Flutter 中文开发者网站 - Flutter 下载后解压…

androidapp的开发流程,王者笔记

昨天去面了一家公司&#xff0c;价值观有受到冲击。 面试官技术方面没的说&#xff0c;他可能是个完美主义的人&#xff0c;无论什么事情到了他那里好像都有解决的方案&#xff0c;我被说的无所适从&#xff0c;感觉他很厉害。 但我不能认可的是&#xff0c;面试官觉得加班是…

会计师人物百度百科词条如何创建?腾轩科技传媒分享创建技巧不容你错过!

随着社交网络的发展&#xff0c;人物在互联网上的影响力变得越来越大。随之而来的是大家都希望在网络上拥有自己的百度百科词条&#xff0c;让更多人了解自己的事业和成就。腾轩科技传媒将为大家介绍会计师人物百度百科词条如何创建&#xff1f;人物百度百科创建技巧不容你错过…

32单片机基础:GPIO输入

1.1按键控制LED 按键介绍&#xff1a; 两种方式&#xff0c;我们一般用下接的方式。 第一个图&#xff1a;注意点。当按键按下&#xff0c;PA0接地&#xff0c;被置为低电平&#xff0c; 但是一旦按键松手&#xff0c;PA0悬空&#xff0c;引脚电压不确定。所以无论怎么读引脚…

Qt程序设计-柱状温度计自定义控件实例

Qt程序设计-柱状温度计自定义控件实例 本文讲解Qt柱状温度计自定义控件实例。 效果演示 创建温度计类 #ifndef THERMOMETER_H #define THERMOMETER_H#include <QWidget> #include <QPainter> #include <QDebug> #include <QTimer> #include <QPr…

element ui富文本编辑器的使用(quill-editor)

引用组件 <el-form-item label"内容"><editor v-model"obj.activity_content" :min-height"192"/> </el-form-item> 组件封装 <template><div><el-upload:action"uploadUrl":before-upload"…

开发知识点-Python-conda

Python-conda https://conda.io/miniconda.html conda search python conda env list conda deactivate conda activate python11 conda 是一个流行的开源包管理系统&#xff0c;它支持多种 Python 版本。 使用 conda 来创建和管理不同的 Python 环境&#xff0c;并在这些环…

电商网站数据采集配合socks5代理ip怎么进行?

电商网站数据采集是一项重要的任务&#xff0c;可以帮助企业了解市场需求、竞品分析、用户行为等方面。在进行电商网站数据采集时&#xff0c;有时需要配合使用socks5代理IP。本文将介绍如何进行电商网站数据采集配合socks5代理IP。 一、代理IP介绍 代理IP是一种可以隐藏用户真…

可用于智能客服的完全开源免费商用的知识库项目

介绍 FastWiki项目是一个高性能、基于最新技术栈的知识库系统&#xff0c;专为大规模信息检索和智能搜索设计。利用微软Semantic Kernel进行深度学习和自然语言处理&#xff0c;结合.NET 8和MasaBlazor前端框架&#xff0c;后台采用.NET 8MasaFrameworkSemanticKernel&#xff…

HTML5:七天学会基础动画网页4

backgorund-size 值与说明 length(单位像素):设置背景图片高度和宽度&#xff0c;第一个值设置宽度&#xff0c;第二个值设置高度&#xff0c;如果只给出一个值&#xff0c;第二个是设置为auto。 percentage(百分比):以父元素的百分比来设置背景图像的宽度和高度&#xff0c…

Mac电脑输入正确密码后提示密码错误

&#x1f3dd; 背景 Mac Pro 在擦键盘时&#xff0c;屏幕一直亮起&#xff0c;导致密码一致输入错误&#xff0c;想来没有什么问题便没有处理。但是&#xff01;&#xff01;&#xff01;在擦完键盘后输入正确的密码依旧提示密码错误&#x1f631; 接下来就是不断的重启、关机…

黑马c++ STL部分 笔记(3) vector容器

vector可以动态扩展&#xff08;不是在原有基础上扩展&#xff0c;而是找更大空间&#xff0c;然后将元数据拷贝新空间&#xff0c;释放原空间&#xff09; vector容器的迭代器是支持随机访问的迭代器 1. vector容器的构造 // vector容器的构造&#xff08;一般用拷贝构造&am…

备战蓝桥杯---树形DP基础3

上一次我们讲了二叉苹果树&#xff0c;现在我们加一点难度&#xff0c;从二叉变成了多叉苹果树。 这样子我们就不可以直接按照上次的方法DP&#xff0c;我们其实可以发现&#xff0c;我们可以用类似背包的思想求解&#xff0c;这就是所谓的树上背包。 我们先加进第一个儿子来…

基于JAVA+Springboot+Thymeleaf前后端分离项目:共享会议室预约系统设计与实现

博主介绍&#xff1a;黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者&#xff0c;CSDN博客专家&#xff0c;在线教育专家&#xff0c;CSDN钻石讲师&#xff1b;专注大学生毕业设计教育和辅导。 所有项目都配有从入门到精通的基础知识视频课程&#xff…

Springboot解决模块化架构搭建打包错误找不到父工程

Springboot解决模块化架构搭建打包错误找不到父工程 一、情况一找不到父工程依赖1、解决办法 二、情况二子工程相互依赖提示"程序包xxx不存在" 一、情况一找不到父工程依赖 报错信息 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-deploy-plugin:…

24计算机考研深大经验分享(计算机专业考研综合安排)

文章目录 背景科目选择高数选课一轮二轮冲刺阶段 线代一轮二轮 概率论计算机学科专业基础408数据结构计算机组成原理操作系统计算机网络总结 英语政治 末言 背景 首先贴一下初试成绩。这篇分享主要是给零基础的同学使用的&#xff0c;基础好的同学可以自行了解补充一下&#xf…

Jmeter系列(5)线程数到底能设置多大

疑惑 一台设备的线程数到底可以设置多大&#xff1f; 线程数设置 经过一番搜索找到了这样的答案&#xff1a; Linux下&#xff0c;2g的 java内存&#xff0c;1m 的栈空间&#xff0c;最大启动线程数2000线程数建议不超过1000jmeter 能启动多少线程&#xff0c;由你的堆内存…
推荐文章