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要使用preventDefault
        class 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反之Login
                return <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.mfbz.cn/a/419280.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

X-pin扁线电机制造工艺复杂 联合电子率先实现其量产

X-pin扁线电机制造工艺复杂 联合电子率先实现其量产 扁线电机是扁平铜包线绕组的电机。扁线电机是目前主流电机绕组形式&#xff0c;根据技术路线不同&#xff0c;扁线电机分为I-pin扁线电机、Hair-pin扁线电机、X-pin扁线电机等&#xff0c;其中X-pin扁线电机是指采用X-pin绕组…

utniy urp shinyssrr插件使用

文章目录 前言步骤1首先在URP的配置文件里添加SSR后处理2 修改RenderingPath为延迟渲染3 启用深度纹理4 为物体添加脚本 插件下载 前言 用来实现屏幕空间反射效果 unity 版本为2021.3.8LTS&#xff0c;低版本的untiy URP的参数设置位置z可能会不同 步骤 1首先在URP的配置文件…

专访win战略会任志雄:澳门旅游业复苏 挖掘游客消费潜力

南方财经:各个国家地区的客商都有不同文化背景和消费习惯,应如何更好吸引外地客商来澳门? win战略会任志雄:首先,周边国家的市场潜力都非常大,包括韩国、日本、越南和印度。 这些年来,这些国家的经济增长都很高,居民的出游比重也在持续增加,如果他们国家的居民把澳门作为一个重…

初学JavaWeb开发总结

0 什么是Web开发 Web: 全球广域网&#xff0c;又称万维网(www World Wide Web)&#xff0c;能够通过浏览器访问的网站。 Web开发&#xff0c;就是开发网站的&#xff0c;如&#xff1a;淘宝、京东等等。 1 网站的工作流程 流程&#xff1a; 浏览器先向前端服务器请求前端资…

一文看清楚流程自定义表单究竟好不好用

提升办公协作效率、做好数据资源利用率的话&#xff0c;可以用什么样的软件实现&#xff1f;在低代码技术平台领域奋斗多年&#xff0c;流辰信息服务商可以给大家推荐专用的流程自定义表单及低代码技术平台整套服务方案。如果你想知道流程自定义表单好不 好用&#xff0c;有什么…

idc业务具体包含哪些业务

IDC业务&#xff0c;即互联网数据中心业务&#xff0c;是指提供互联网基础设施服务的一种商业模式。它包括了许 多不同的业务&#xff0c;每个业务都有其特定的功能和用途。下面将详细介绍IDC业务具体包含哪些业务。 1. 服务器托管服务&#xff1a; 服务器托管是IDC业务中最基…

transformer--解码器

在编码器中实现了编码器的各种组件&#xff0c;其实解码器中使用的也是这些组件&#xff0c;如下图&#xff1a; 解码器组成部分: 由N个解码器层堆叠而成每个解码器层由三个子层连接结构组成第一个子层连接结构包括一个多头自注意力子层和规范化层以及一个残差连接第二个子层连…

<专利>机器人3D视觉快速定位抓取方法及系统

摘要&#xff0c;此专利无可用的关键技术信息&#xff0c;基本都是下面几句话反复说。。。 本发明提供了一种机器人3D快速定位抓取方法及系统&#xff0c; 包括&#xff1a; 通过高速的3D结构光成像对目标物体的表面轮廓进行扫描&#xff0c; 形成点云数据&#xff1b;对所述点…

浅谈排序算法(冒泡,插入,归并)

对于数据的排序&#xff0c;有多种方法&#xff0c;对应这不同的时间复杂度&#xff08;效率不同&#xff09;。 ​一、冒泡排序&#xff08;Bubble Sort&#xff09; 冒泡排序&#xff08;Bubble Sort&#xff09;是一种简单的排序算法。 算法思路&#xff1a; 1. 从第一对相…

利用 Python 抓取数据探索汽车市场趋势

一、引言 随着全球对环境保护意识的增强和技术的进步&#xff0c;新能源汽车作为一种环保、高效的交通工具&#xff0c;正逐渐受到人们的关注和青睐。在这个背景下&#xff0c;对汽车市场的数据进行分析和研究显得尤为重要。 本文将介绍如何利用 Python 编程语言&#xff0c;结…

扭蛋机小程序开发,线上扭蛋机成为市场发展主流?

近几年以来&#xff0c;潮玩市场一直处于领先状态&#xff0c;市场规模逐渐扩大。在潮玩行业中&#xff0c;除了盲盒&#xff0c;受到各大群体喜欢的就是扭蛋机了&#xff0c;它因为价格低、品类多样、收藏价值高的优势吸引了各个群体的消费者。 当下&#xff0c;线上用户体量…

基于springboot + vue实现的前后端分离-在线旅游网站系统(项目 + 论文)

项目介绍 本旅游网站系统采用的数据库是MYSQL &#xff0c;使用 JSP 技术开发&#xff0c;在设计过程中&#xff0c;充分保证了系统代码的良好可读性、实用性、易扩展性、通用性、便于后期维护、操作方便以及页面简洁等特点。 技术选型 后端: SpringBoot Mybatis 数据库 : MyS…

★【二叉搜索树】【中序遍历+前后指针】Leetcode 530. 二叉搜索树的最小绝对差

★【二叉搜索树】【中序遍历前后指针】Leetcode 530. 二叉搜索树的最小绝对差 解法1 笨方法 中序遍历转化为有序数组之后遍历解法2 记忆一下&#xff01;&#xff01;&#xff01;需要用一个pre节点记录一下cur节点的前一个节点 遇到在二叉搜索树上求什么最值&#xff0c;求差…

一篇教会你升级GPT-4,内附详细步骤(24年3月最新)

先介绍一下 GPT 升级 第一种: 支付宝购买礼品卡给美区 Apple ID 充值 第二种&#xff1a;3分钟快速升级方法&#xff08;一键升级&#xff09; GPT4的作用非常强大&#xff0c;还可以使用DALL进行绘画&#xff0c;比如我画一个小王子的插画&#xff1a; 平时用DALL绘画是比较…

事物

概述&#xff1a; 数据库的事务&#xff08;Transaction&#xff09;是一种机制、一个操作序列&#xff0c;包含了一组数据库操作命令。 事务把所有的命令作为一个整体一起向系统提交或撤销操作请求&#xff0c;即这一组数据库命令要么同时成功&#xff0c;要么同时失败。 事…

SpringCloud搭建微服务之Consul服务配置

1. 概述 前面有介绍过Consul既可以用于服务注册和发现&#xff0c;也可以用于服务配置&#xff0c;本文主要介绍如何使用Consul实现微服务的配置中心&#xff0c;有需要了解如何安装Consul的小伙伴&#xff0c;请查阅SpringCloud搭建微服务之Consul服务注册与发现 &#xff0c…

Ubuntu系统使用Docker搭建Jupyter Notebook并实现无公网ip远程连接

文章目录 1. 选择与拉取镜像2. 创建容器3. 访问Jupyter工作台4. 远程访问Jupyter工作台4.1 内网穿透工具安装4.2 创建远程连接公网地址4.3 使用固定二级子域名地址远程访问 本文主要介绍如何在Ubuntu系统中使用Docker本地部署Jupyter Notebook&#xff0c;并结合cpolar内网穿透…

用GGUF和Llama.cpp量化Llama模型

用GGUF和Llama .cpp量化Llama模型 什么是GGML如何用GGML量化llm使用GGML进行量化NF4 vs. GGML vs. GPTQ结论 由于大型语言模型&#xff08;LLMS&#xff09;的庞大规模&#xff0c;量化已成为有效运行它们的必要技术。通过降低其权重的精度&#xff0c;您可以节省内存并加快推理…

JavaScript数据类型 检测数据类型 数据类型转换 数值相等比较

数值相等比较 JavaScript 提供三种不同的值比较运算&#xff1a; ——严格相等&#xff08;三个等号&#xff09; ——宽松相等&#xff08;两个等号&#xff09; 8种数据类型 前七种为基础数据类型。 Object类型为引用数据类型。 数据类型概念以及存储方式 let a {name:…

MySQL:常用的SQL语句

提醒&#xff1a;设定下面的语句是在数据库名为 db_book执行的。 一、创建表 1. 创建t_booktype表 USE db_book; CREATE TABLE t_booktype(id INT AUTO_INCREMENT, bookTypeName VARCHAR(20),bookTypeDesc varchar(200),PRIMARY KEY (id) );2. 创建t_book表 USE db_book; C…