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 的方式,事件对象以及更多的参数将会被隐式的进行传递。

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

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

相关文章

MDK-ARM 编译后 MAP 文件分析

本文配合 STM32 堆栈空间分布 食用更佳&#xff01; 一图胜千言。。。

pytorch十大核心操作

PyTorch的十大核心操作涵盖了张量创建、数据转换、操作变换等多个方面。以下是结合参考文章信息整理出的PyTorch十大核心操作的概述&#xff1a; 张量创建&#xff1a; 从Python列表或NumPy数组创建张量。使用特定值创建张量&#xff0c;如全零、全一、指定范围、均匀分布、正…

开发环境安装---Visual Studio Code

开发环境安装---Visual Studio Code 1.官网下载Visual Studio Code2.安装步骤3.安装插件 1.官网下载Visual Studio Code VScode: https://code.visualstudio.com/ Visual Studio Code 简称 VSCode &#xff0c;2015 年由微软公司发布。可用于 Windows&#xff0c;macOS 和 Li…

1panel

0&#xff09;VMware安装CentOS 0.1&#xff09;确保有网络 0.2&#xff09;安装依赖环境 yum -y install yum-utils device-mapper-persistent-datalvm21&#xff09;切换阿里镜像源 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/doc…

HTML(17)——圆角和盒子阴影

盒子模型——圆角 作用&#xff1a;设置元素的外边框为圆角 属性名&#xff1a;border-radius 属性值&#xff1a;数字px/百分比 也可以每个角设置不同的效果&#xff0c;从左上角顺时针开始赋值&#xff0c;没有取值的角与对角取值相同。 正圆 给正方形盒子设置圆角属性…

数据库实战(二)(引言+关系代数)

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;数据库 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 前言 常见概念 一、什么是数据库&#xf…

【鸿蒙】HUAWEI DevEco Studio安装

HUAWEI DevEco Studio介绍 面向HarmonyOS应用及元服务开发者提供的集成开发环境(IDE)&#xff0c; 助力高效开发。 DevEco Studio当前最新版本是&#xff1a; 3.1。 DevEco Studio计划里程碑 版本类型说明 下载 下载网址&#xff1a;DevEco Studio安装包官⽅下载 双击运行…

git 提交代码的常用命令

一. 简介 本文简单学习一下&#xff0c;如何使用 git命令&#xff0c;从 gerrit下拉代码&#xff0c;创建分支&#xff0c;或者将代码&#xff08;暂时&#xff09;存入栈区&#xff0c;或者向 gerrit提交代码等等一些操作。 二. git 创建、切换分支&#xff0c;提交代码的常…

C++ | Leetcode C++题解之第169题多数元素

题目&#xff1a; 题解&#xff1a; class Solution { public:int majorityElement(vector<int>& nums) {int candidate -1;int count 0;for (int num : nums) {if (num candidate)count;else if (--count < 0) {candidate num;count 1;}}return candidate;…

STM32通过Flymcu串口下载程序

文章目录 1. Flymcu 2. 操作流程 2.1 设备准备 2.2 硬件连接 2.3 设置BOOT引脚 2.4 配置 2.5 下载程序 1. Flymcu Flymcu软件可以通过串口给STM32下载程序&#xff0c;如果没有STLINK的时候&#xff0c;就可以使用这个来烧录程序。软件不用安装&#xff0c;直接打开就行…

Windows11+CUDA12.0+RTX4090如何配置安装Tensorflow2-GPU环境?

1 引言 电脑配置 Windows 11 cuda 12.0 RTX4090 由于tensorflow2官网已经不支持cuda11以上的版本了&#xff0c;配置cuda和tensorflow可以通过以下步骤配置实现。 2 步骤 &#xff08;1&#xff09;创建conda环境并安装cuda和cudnn&#xff0c;以及安装tensorflow2.10 con…

【代码随想录算法训练Day44】LeetCode 322.零钱兑换、LeetCode 279.完全平方数、LeetCode139.单词拆分

Day44 动态规划第六天 LeetCode 322.零钱兑换 dp数组的含义&#xff1a;装满容量为j的背包需要的最少物品数为dp[j] 递推公式&#xff1a;dp[j]min(dp[j-coins[i]]1,dp[j]) 初始化&#xff1a;dp[0]0,dp[j]INT_MAX 遍历顺序&#xff1a;个数问题与遍历顺序无关&#xff0c;都…

[Python学习篇] Python字典

字典是一种可变的、无序的键值对&#xff08;key-value&#xff09;集合。字典在许多编程&#xff08;Java中的HashMap&#xff09;任务中非常有用&#xff0c;因为它们允许快速查找、添加和删除元素。字典使用花括号 {} 表示。字典是可变类型。 语法&#xff1a; 变量 {key1…

等保2.0时代下的安全体系的构建

一、等保2.0的背景与要求 等保2.0&#xff0c;即网络安全等级保护2.0&#xff0c;是我国网络安全领域的一项基本国策和基本制度。它的核心在于构建一套适应不同网络环境和保护对象的安全保护标准和技术要求&#xff0c;以应对日益复杂多变的网络安全威胁。 等保2.0的实施&…

lighttpd cgi不能重启

1. 背景 cgi出现coredump后&#xff0c;lighttpd不能拉动cgi重启。 2. 重现问题 2.1. cgi实现 /*! cgi简单实现 */ #include <stdio.h> #include <fcgiapp.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h> #include <s…

tcp 粘包和拆包 及 解决粘包方案

什么是粘包和拆包 .TCP 是面向连接的&#xff0c;面向流的&#xff0c;提供高可靠性服务。收发两端&#xff08;客户端和服务器端&#xff09;都要有一一成对的 socket&#xff0c;因此&#xff0c;发送端为了将多个发给接收端的包&#xff0c;更有效的发给对方&#xff0c;使…

CIRCOS圈图绘制 - circos安装

Circos是绘制圈图的神器&#xff0c;在http://circos.ca/images/页面有很多CIRCOS可视化的示例。 Circos可以在线使用&#xff0c;在线使用时是把表格转为圈图&#xff0c;不过只允许最大75行和75列&#xff1b;做一些简单的示意图会比较好&#xff0c;最后时会介绍下在线的tab…

anaconda-pip源

在Anaconda环境中&#xff0c;使用pip安装Python包时&#xff0c;默认的PyPI源可能会因网络问题导致下载速度慢或无法连接。为了解决这个问题&#xff0c;可以将pip的默认源更换为国内的镜像源。以下是在Anaconda中如何进行pip换源的详细步骤&#xff1a; 1. 打开Anaconda Pro…

第二十四篇——纠错码:对待错误的正确态度是什么?

目录 一、背景介绍二、思路&方案三、过程1.思维导图2.文章中经典的句子理解3.学习之后对于投资市场的理解4.通过这篇文章结合我知道的东西我能想到什么&#xff1f; 四、总结五、升华 一、背景介绍 当我们面对错误的发生&#xff0c;是一个确定事件的时候&#xff1b;我们…

十大机器学习算法深入浅出

本栏目涉及对于回归算法、聚类算法、决策树、随机森林、神经网络、贝叶斯算法、支持向量机等十大机器学习算法的笔记 下面是笔记大纲&#xff0c;具体内容可查看**“十大机器学习算法深入浅出”**专栏&#xff0c;内容持续更新&#xff0c;欢迎订阅专栏和专注我&#xff01; 1…