React之组件定义和事件处理

news2024/9/24 18:14:56

一、组件的分类

在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.coloradmin.cn/o/1483227.html

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

相关文章

Linux学习笔记:进程的终止和等待

进程终止和等待 进程终止进程退出场景进程常见退出方式_exit()退出exit()退出return退出exit()与_exit()的不同之处 进程的等待什么是进程等待?为什么要进行进程等待如何进行等待wait方式:waitpid方式 进程终止 进程退出场景 一般来讲,进程的退出场景有三种: 代码运行完毕,…

chalk库的使用

这篇文章主要是对chalk库官方文档的中文翻译以及我自己的一些理解。chalk的官方文档可以看这里。 首先说下chalk库的作用&#xff1a;美化终端输出的文本&#xff0c;例如添加不同的字体颜色、不同颜色的背景、粗体以及添加下划线等等&#xff0c;看下图&#xff1a; 优点 富…

Vue2->3

Vue2->3 认识Vue31. Vue2 选项式 API vs Vue3 组合式API2. Vue3的优势 使用create-vue搭建Vue3项目1. 认识create-vue2. 使用create-vue创建项目 熟悉项目和关键文件组合式API - setup选项1. setup选项的写法和执行时机2. setup中写代码的特点3. <script setup>语法糖…

基于springboot+vue的社区养老服务平台

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

Kali Linux 安装 + 获取 root 权限 + 远程访问

一、什么是Kali kali是linux其中一个发行版&#xff0c;基于Debian&#xff0c;前身是BackTrack&#xff08;简称BT系统&#xff09;。kali系统内置大量渗透测试软件&#xff0c;可以说是巨大的渗透系统&#xff0c;涵盖了多个领域&#xff0c;如无线网络、数字取证、服务器、密…

【MySQL】表的内连和外连(重点)

表的连接分为内连和外连。 一、内连接 内连接实际上就是利用 where 子句对两种表形成的笛卡儿积进行筛选&#xff0c;前面学习的查询都是内连接&#xff0c;也是在开发过程中使用的最多的连接查询。 select 字段 from 表1 inner join 表2 on 连接条件 and 其他条件; 注意&…

Java核心技术知识导航(周更)

写在文章开头 面试旺季笔者也收到很多读者的私信&#xff0c;所以笔者就对近期不断更新迭代补充的Java核心知识点进行一个导航汇总。感兴趣的读者建议收藏&#xff0c;这些专栏系列笔者会在每个周末进行迭代、补充、更新&#xff0c;希望对你有帮助。 你好&#xff0c;我叫sh…

算法学习路径图

1.总览 算法学习路径 2.学习资料 2.1 Java算法与数据结构 Java算法与数据结构

【C++提高编程】

C提高编程 C提高编程1 模板1.1 模板的概念1.2 函数模板1.2.1 函数模板语法1.2.2 函数模板注意事项1.2.3 函数模板案例1.2.4 普通函数与函数模板的区别1.2.5 普通函数与函数模板的调用规则1.2.6 模板的局限性 1.3 类模板1.3.1 类模板语法1.3.2 类模板与函数模板区别1.3.3 类模板…

运筹学_1.1.2 线性规划问题-图解法

1.1.2 线性规划问题-图解法 一、图解法求解步骤&#xff08;只适用于两个决策变量问题&#xff09;二、图解法作图实例三、图解法分析线性规划几种解的情况1、唯一最优解2、无穷多最优解3、无界解4、无解或无可行解 四、图解法的几点启示 一、图解法求解步骤&#xff08;只适用…

内网信息搜集

目录 内网基础知识 基本流程图 怎么判断是否在域内 常规信息类收集-应用&服务&权限等 cs信息搜集 bloodhound安装及使用 内网基础知识 工作组&#xff1a;将不同的计算机按照功能分别列入不同的组&#xff0c;想要访问某个部门的资源&#xff0c;只要在【网络】里…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的钢材表面缺陷检测系统(Python+PySide6界面+训练代码)

摘要&#xff1a;开发钢材表面缺陷检测系统对于保障制造质量和提高生产效率具有关键作用。本篇博客详细介绍了如何运用深度学习构建一个钢材表面缺陷检测系统&#xff0c;并提供了完整的实现代码。该系统基于强大的YOLOv8算法&#xff0c;并对比了YOLOv7、YOLOv6、YOLOv5&#…

【服务器数据恢复】昆腾存储中raid5磁盘阵列数据恢复案例

服务器数据恢复环境&故障&#xff1a; 10个磁盘柜&#xff0c;每个磁盘柜配24块硬盘。9个磁盘柜用于存储数据&#xff0c;1个磁盘柜用于存储元数据。 元数据存储中24块硬盘&#xff0c;组建了9组RAID1阵列1组RAID10阵列&#xff0c;4个全局热备硬盘。 数据存储中&#xff0…

Vue.js的双向绑定原理

Vue的双向绑定 vue双向绑定是其最重要的核心亮点&#xff0c;其原理也很简单&#xff0c;这里做个简单总结 vue2的双向绑定是利用的Object.definePropertyvue3的双向绑定是利用的 ES6Porxy中的defineProperty(target, propKey, propDesc 其作用类似于Object.defineProperty …

水库安全监测方案(福建地区水库安全监测案例分享)

我司星创易联最近在福建省受到了一个水库安全监测系统项目的委托。该水库位于福建中部山区,作为该地区的重要防洪与供水工程,对下游数十万人的生活产生重大影响。但是因为水库附近地质情况复杂,水库大坝在多次洪水冲击下出现一定病害,亟须全面加强对水库大坝安全状况的监测,以确…

C语言---文件操作(1)

1.文件的打开和关闭 fopen有2个参数&#xff0c;第一个是文件的名字&#xff0c;第二个是打开的模式&#xff08;例如是读文件还是写文件&#xff09; (1)该文件夹下面没有data.txt文件&#xff0c;但是我执行了read操作&#xff0c;所以会显示这样的错误 &#xff08;2&#…

php httpfs链接hdfs

一.代码&#xff08;有bug&#xff09; GitHub - michaelbutler/php-WebHDFS: A PHP client for WebHDFS 二.调用代码 1.代码1.代码 require_once(../webhdfs/src/org/apache/hadoop/WebHDFS.php);require_once(../webhdfs/src/org/apache/hadoop/tools/Curl.php); require_o…

YOLOv5 + Flask + Vue实现基于深度学习算法的垃圾检测系统源码+数据库

✨界面展示 登录 注册 垃圾检测 用户管理 404 Not Found页面 403 拒绝访问页面 黑暗模式 深蓝模式 灰色模式 色弱模式 ✨技术特性 深度学习 YOLOv5&#x1f680;&#xff1a;高效、准确的目标检测算法&#xff0c;实时识别检测图像和视频中的各种对象PyTorch&#xff1a;机器…

对于《幻兽帕鲁》这样的游戏,如何优化服务器性能以提高游戏体验?

对于《幻兽帕鲁》这样的游戏&#xff0c;如何评估和优化服务器性能以提高游戏体验&#xff1f; 硬件配置优化&#xff1a;选择高性能的服务器&#xff0c;如4核16G的幻兽帕鲁服务器&#xff0c;这样可以保证有足够的计算性能和内存容量来支持游戏的运行。同时&#xff0c;考虑到…

k8s-kubeapps图形化管理 21

结合harbor仓库 由于kubeapps不读取hosts解析&#xff0c;因此需要添加本地仓库域名解析&#xff08;dns解析&#xff09; 更改context为全局模式 添加repo仓库 复制ca证书 添加成功 图形化部署 更新部署应用版本 再次进行部署 上传nginx 每隔十分钟会自动进行刷新 在本地仓库…