React是怎么进行事件处理的

什么是事件?

事件是指一些可以通过脚本响应的页面动作。当用户按下鼠标或者提交一个表单等等时候,事件都会出现。事件处理是一段JavaScript代码,总是与页面中的特定部分以及一定的事件相关联。当与页面特定部分相关联的事件发生时,事件处理器就会被调用。

JavaScript常用事件

image.png

React的事件处理

React 元素的事件处理和 DOM 元素的很相似。但是React的两点最大的不同是

  1. React 事件的命名采用小驼峰式(camelCase),而不是纯小写。
  2. 使用 JSX 语法时你需要传入一个函数作为事件处理函数,而不是一个字符串。

阻止默认行为

注意: 在 React 中另一个不同点是你不能通过返回 false 的方式阻止默认行为。你必须显式的使用 preventDefault

代码示例:
原生写法:

<a href="#" onclick="console.log('The link was clicked.'); return false">
  Click me
</a>

我们返回了false后会阻止<a>标签的原始跳转功能。只执行我们的console.log

React写法:

    function ActionLink() {
      function handleClick(e) {    e.preventDefault();    console.log('The link was clicked.');  }
      return (
        <a href="#" onClick={handleClick}>      Click me
        </a>
      );

功能上是和上面的代码一样的。但是在这里,e 是一个合成事件。React 根据 W3C 规范来定义这些合成事件,所以你不需要担心跨浏览器的兼容性问题。

为DOM元添加监听器

React不需要使用 addEventListener 为已创建的 DOM 元素添加监听器。只需要在该元素初始渲染的时候添加监听器即可。

代码示例:

    定义一个Toggle组件,当我们点击按钮时会切换我们按钮中的值,一直在NOOFF中切换。
    class Toggle extends React.Component {
      constructor(props) {
        super(props);
        this.state = {isToggleOn: true};

        // 为了在回调中使用 `this`,这个绑定是必不可少的   
        this.handleClick = this.handleClick.bind(this);  
        }
            执行我们的切换事件,切换state值
      handleClick() {  
          this.setState(state => ({ 
          进行取反
          isToggleOn: !state.isToggleOn    
          })); 
          }
          
      render() {
        return (
          <button onClick={this.handleClick}>      
          {this.state.isToggleOn ? 'ON' : 'OFF'}
          </button>
        );
      }
    }

    ReactDOM.render(
      <Toggle />,
      document.getElementById('root')
    );

注意: 我们必须谨慎对待 JSX 回调函数中的 this,因为在 JavaScript 中,class 的方法默认不会绑定 this。如果你忘记绑定 this.handleClick 并把它传入了 onClick,当你调用这个函数的时候 this 的值为 undefined。因为this 本质上就是指向它的调用者,this 是在函数运行时才绑定,在JavaScript 中普通函数都是 window 调用的,所以指向 window但是我们的JSX 语法是不被 webpack 识别的,webpack 默认只能处理 .js 后缀名的文件,所以需要借助 Babel 这个 JavaScript 编译器,而 babel 开启了严格模式 ,开启了严格模式下无法再意外创建全局变量。所以this指向的是 undefined。

解决React组件this指向问题的两种方法

方法一、在构造函数中使用bing

    class index extends Component {
        constructor(){
            super()
            this.speak = this.speak.bind(this)
            /*解决类中的this问题:this.speak = this.speak.bind(this),构造器里面的this默认指向实例对象,
          实例对象通过原型链在类的原型上找着fnc函数,通过bind函数将其this指向改为实例对象,并返回一个新的函数
          再将这个新的函数给实例,并取名为fnc*/
        }
        speak(){
            console.log(this)//输出当前实例对象
        }
        render() {
            return (
                <div>
                    <button onClick={this.speak}>按钮</button>
                </div>
            )
        }
    }

为什么是bind呢?

众所周知call、apply、bind 都可以改变我们的this指向。那为什么是bind呢?

区别:

  • call 和 bind 可以直接接受多个参数 apply 则是将参数放进一个数组
  • call 和 apply 返回立即执行函数,bind 返回新的函数,bind()() 也是立即执行
  • call和apply都是临时改变一次this指向,并立即执行。而bind是返回一个永久改变this指向的函数。使用 bind 绑定 this 后,该函数里面的 this 不能变化了,不论是谁调用

方法二、将箭头函数赋值给类的属性

    class index extends Component { 
        speak = () =>{ 
            console.log(this)
     } 
         render() { 
             return ( 
                 <div> 
                 <button onClick={this.speak}>按钮</button> 
                 </div> 
               ) 
          }
     }//需要传参的话,可以使用函数柯里化的思想

为什么什么箭头函数没影响呢?

箭头函数:箭头函数并不会创建自己的执行上下文,所以箭头函数中的this都是外层的this,会向外作用域中,一层层查找this,直到有 this 的定义

注意:性能存在差异

使用箭头函数来解决性能会比较低,因为箭头函数不是方法,它们是匿名函数表达式,所以将它们添加到类中的唯一方法是赋值给属性。前面介绍ES6的类的时候可以看出来,ES 类以完全不同的方式处理方法和属性

方法被添加到类的原型中,而不是每个实例定义一次。

类属性语法是为相同的属性分配给每一个实例的语法糖,实际上会在 constructor里面这样实现:

    constructor(){
        super()
        this.speak = () => {console.log(this)}
    }

这意味着新实例被创建时,函数就会被重新定义,丢失了JS实例共享原型方法的优势。而方法一,只是在生成实例时多了一步 bind 操作,在效率与内存占用上都有极大的优势

向事件处理程序传递参数

在循环中,通常我们会为事件处理函数传递额外的参数。例如,若 id 是你要删除那一行的 ID,以下两种方式都可以向事件处理函数传递参数:

    <button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
    //推荐第二种
    <button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

在这两种情况下,React 的事件对象 e 会被作为第二个参数传递。如果通过箭头函数的方式,事件对象必须显式的进行传递,而通过 bind 的方式,事件对象以及更多的参数将会被隐式的进行传递。

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

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

相关文章

文本三剑客其二

文本三剑客其二 sed和awk grep就是查找文本当中的内容&#xff0c;扩展正则表达式。 sed 对文本内容进行增删改查 sed是一种流编辑器&#xff0c;一次处理一行内容。 如果只是展示&#xff0c;会放在缓冲区&#xff08;模式空间&#xff09;&#xff0c;展示结束之后&…

vue3自动导入---组件库elements-ui,vuetify以及scss样式的自动导入

自动导入 我们在使用第三方组件库和css样式文件时&#xff0c;都需要进行引入&#xff0c;可以在单个组件内单独引用&#xff0c;也可以在全局引入或一次引入所有组件&#xff1b;但是&#xff0c;一般情况下我们都不会全部引入&#xff0c;这会是打包的结果变大&#xff0c;而…

idea插件开发之如何获取用户输入的变量名(类变量,局部变量等)

写在前面 比如我们要开发一个变量名称补全功能的插件&#xff0c;此时就需要在用户输入时获取当前的最新输入内容&#xff0c;本文就来看下如何来做。 1&#xff1a;开发 首先我们需要创建一个CompletionContributor的子类&#xff0c;还需要一个CompletionProvider的子类来…

【权威发布】2024年环境科学、旅游与产业经济国际会议(ICESTIE 2024)

2024年环境科学、旅游与产业经济国际会议 2024 International Conference on Environmental Science, Tourism and Industrial Economics 会议简介 2024年环境科学、旅游与产业经济国际会议旨在汇聚全球该领域的专家学者&#xff0c;共同探讨环境科学与旅游产业的融合发展&…

ArcGIS图斑分区(组)排序—从上到下从左到右

​​ 点击下方全系列课程学习 点击学习—>ArcGIS全系列实战视频教程——9个单一课程组合系列直播回放 ArcGIS图斑分区&#xff08;组&#xff09;从上到下从左到右排序 是之前的内容的升级 GIS技巧100例——12ArcGIS图斑空间排序 关于今天的内容 我们在19年已经和大家分…

vue3 中实现 验证码发送 刷新不变倒计时

今天实现一个倒计时的功能 在平常开发前端的功能的时候 不管是 移动端还是web端 我们都会有注册 登录 中的发送验证码功能 实现绑定以及注册功能。今天我主要分享一下当前的验证码实现原理。 有两种做法(我目前认为以及看到的) ① 做一个简单的倒计时 ② 实时监测倒计时 刷…

食品行业BC一体化运营方案

一、引言 在当前的市场环境下&#xff0c;食品行业面临着日益激烈的竞争和不断变化的消费者需求。传统的经营模式已无法满足现代消费者对高效、便捷和个性化服务的要求。因此&#xff0c;实施BC&#xff08;Business to Consumer&#xff09;一体化运营方案成为必然选择。通过…

顶顶通呼叫中心中间件-替换授权文件使授权文件生效指南

一、登录my.ddrj.com下载授权文件 登录地址&#xff1a;用户-顶顶通授权管理系统 登录之后正式授权然后点击查看把license.json下载下来&#xff0c;然后替换到fs的授权文件路径&#xff0c;默认路径是&#xff1a;/ddt/fs/conf 如果安装路径不一样就需要自己去看看授权文件存…

分流电阻器的原理、特性、参数要点及其与分压电阻的区别详解

分流电阻器是一种低阻值电阻器&#xff0c;设计用于在电路中并联连接&#xff0c;以提供一个低阻抗的旁路或分流路径&#xff0c;从而使得一部分电流可以通过这个路径流动。它的主要功能是测量或限制电流&#xff0c;尤其适用于大电流检测的应用场景。分流电阻通过在其两端产生…

windows下cmd命令行模式中cd变换路径命令无效的解决办法

一&#xff0c;出现的情况 二&#xff0c;解决方法 当出现转换盘的时候打开 cmd 之后可能是无法生效的 &#xff0c;因为在cmd 中转换盘首先需要用到换盘符 。 Solve1 : 先进行换盘 C: c: // 转换到 C盘 D: d: // 转化到 D盘 Solve2 : 直接进行强转 cd /dE:\ACM算法资源\XCP…

如何使用mvnd,随着mvnd的1.0.0发布,Maven构建速度提升了3倍不止。

maven-mvnd-1.0.0-m8-m40-windows-amd64 1、什么是 Mvnd呢 Mvnd 是 Apache Maven Daemon 的简称&#xff0c;是一个通过 GraalVM 构建的本地可执行文件&#xff0c;用于加速 Maven 构建。Mvnd 的设计理念是通过在后台运行一个守护进程来避免每次构建时启动新的 JVM&#xff0c…

【人机交互 复习】第7章 可视化设计

一、窗口界面类型 1.多文档界面 &#xff08;1&#xff09;优点 a.节省系统资源 b.最小的可视集 c.协同工作区 d.多文档同时可视化 &#xff08;2&#xff09;缺点 a.菜单随活动文档窗口状态变化&#xff0c;导致不一致性 b.文档窗口必须在主窗口内部&#xff0c;减弱多文档显…

易支付宝塔一键部署项目 懒人专用包 制作

宝塔一键部署说明 https://www.bt.cn/bbs/thread-33063-1-1.html 1. auto_install.json {"php_ext":"fileinfo","chmod":[],"success_url":"install/?step3&jump1","php_versions":"80","db…

mybatis查询PostgreSQL报错:无法确定参数 $1 的数据类型

错误信息 ### Cause: org.postgresql.util.PSQLException: 错误: 无法确定参数 $1 的数据类型 ; bad SQL grammar []; nested exception is org.postgresql.util.PSQLException: 错误: 无法确定参数 $1 的数据类型] with root cause org.postgresql.util.PSQLException: 错误: …

Python3,10行代码,从数据库获取各个维度的数据统计,并把结果输出在Excel中。

10行代码自动统计数据 1、引言2、代码实例3、总结 1、引言 小屌丝&#xff1a;鱼哥帮个忙 小鱼&#xff1a;稍等会哦&#xff0c; 小屌丝&#xff1a;好嘞。 小屌丝&#xff1a; 鱼哥&#xff0c; 还没忙完嘛&#xff1f; 小鱼&#xff1a;快了快了&#xff0c; 再耐心等一等…

缓存雪崩(主从复制、哨兵模式(脑裂)、分片集群)

缓存雪崩&#xff1a; 在同一时段大量的缓存key同时失效或者Redis服务宕机&#xff0c;导致大量请求到达数据库&#xff0c;带来巨大压力。 方法一&#xff1a; 给不同key的TTL添加随机值&#xff0c;以此避免同一时间大量key失效。&#xff08;用于解决同一时间大量key过期&…

重学java 81.类的加载时机

不破不立&#xff0c;人类最宝贝的品质就是勇敢和过去告别 —— 24.6.21 一、类的加载时机 1.new对象 2.new子类对象(new子类对象先初始化父类) 3.执行main方法 4.调用静态成员 5.反射,创建Class对象 这五种情况就可以让类加载到内存 类加载过程 1.问题:谁将class文件加载到了…

智能血压计,让健康“听”得见- WT588F02B血压计语音方案

一、语音血压计开发背景&#xff1a; 在快节奏的现代生活中&#xff0c;健康成为了我们最宝贵的财富。而血压&#xff0c;作为反映人体健康状态的重要指标之一&#xff0c;更是需要我们时刻关注。传统的血压计虽然能够为我们提供准确的血压数据&#xff0c;但往往因为操作复杂…

nodejs从基础到实战学习笔记-模块化、包

二、模块化 2.1 什么是模块化 模块化是指解决一个复杂问题时&#xff0c;自顶向下逐层把系统划分成若干模块的过程。对于整个系统来说&#xff0c;模块是可组合、分解和更换的单元。 2.1.1 把代码进行模块化拆分的好处 提高了代码的复用性提高了代码的可维护性可以实现按需…

云计算【第一阶段(18)】磁盘管理与文件系统

一、磁盘基础 磁盘&#xff08;disk&#xff09;是指利用磁记录技术存储数据的存储器。 磁盘是计算机主要的存储介质&#xff0c;可以存储大量的二进制数据&#xff0c;并且断电后也能保持数据不丢失。 早期计算机使用的磁盘是软磁盘&#xff08;Floppy Disk&#xff0c;简称…