在React中如何优雅的处理事件响应详解
发布时间 - 2026-01-11 02:29:20 点击率:次前言

本文主要给大家介绍的是关于React处理事件响应的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍吧。
React中定义一个组件,可以通过React.createClass或者ES6的class。本文讨论的React组件是基于class定义的组件。采用class的方式,代码结构更加清晰,可读性强,而且React官方也推荐使用这种方式定义组件。
处理事件响应是Web应用中非常重要的一部分。React中,处理事件响应的方式有多种。
一、使用箭头函数
先上代码:
//代码1
class MyComponent extends React.Component {
render() {
return (
<button onClick={()=>{console.log('button clicked');}}>
Click
</button>
);
}
}
当事件响应逻辑比较复杂时,再把所有的逻辑直接写在onClick的大括号内,就会导致render函数变得臃肿,不容易直观地看出组件render出的元素结构。这时,可以把逻辑封装成组件的一个方法,然后在箭头函数中调用这个方法。
如下所示:
//代码2
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {number: 0};
}
handleClick() {
this.setState({
number: ++this.state.number
});
}
render() {
return (
<div>
<div>{this.state.number}</div>
<button onClick={()=>{this.handleClick();}}>
Click
</button>
</div>
);
}
}
这种方式最大的问题是,每次render调用时,都会重新创建一个事件的回调函数,带来额外的性能开销,当组件的层级越低时,这种开销就越大,因为任何一个上层组件的变化都可能会触发这个组件的render方法。当然,在大多数情况下,这点性能损失是可以不必在意的。这种方式也有一个好处,就是不需要考虑this的指向问题,因为这种写法保证箭头函数中的this指向的总是当前组件。
二、使用组件方法
代码先:
//代码3
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {number: 0};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState({
number: ++this.state.number
});
}
render() {
return (
<div>
<div>{this.state.number}</div>
<button onClick={this.handleClick}>
Click
</button>
</div>
);
}
}
这种方式的好处是每次render,不会重新创建一个回调函数,没有额外的性能损失。需要注意的是,使用这种方式要在构造函数中为事件回调函数绑定this: this.handleClick = this.handleClick.bind(this) ,否则handleClick中的this是undefined。这是因为ES6 语法的缘故,ES6 的 Class 构造出来的对象上的方法默认不绑定到 this 上,需要我们手动绑定。每次都手动绑定this是不是有点蛋疼?好吧,让我们来看下一种方式。
三、属性初始化语法(property initializer syntax)
使用ES7的 property initializers,代码可以这样写:
//代码4
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {number: 0};
}
handleClick = () => {
this.setState({
number: ++this.state.number
});
}
render() {
return (
<div>
<div>{this.state.number}</div>
<button onClick={this.handleClick}>
Click
</button>
</div>
);
}
}
哈哈,再也不用手动绑定this了。但是你需要知道,这个特性还处于试验阶段,默认是不支持的。如果你是使用官方脚手架Create React App 创建的应用,那么这个特性是默认支持的。你也可以自行在项目中引入babel的transform-class-properties插件获取这个特性支持。
四、回调函数传参问题
事件的回调函数默认是会被传入一个事件对象Event作为参数的。如果我想传入其他参数给回调函数应该怎么办呢?
使用第一种方式的话很简单,直接传就可以了:
//代码5
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
list: [1,2,3,4],
current: 1
};
}
handleClick(item,event) {
this.setState({
current: item
});
}
render() {
return (
<ul>
{this.state.list.map(
(item)=>(
<li className={this.state.current === item ? 'current':''}
onClick={(event) => this.handleClick(item, event)}>{item}
</li>
)
)}
</ul>
);
}
}
使用第二种方式的话,可以把绑定this的操作延迟到render中,在绑定this的同时,绑定额外的参数:
//代码6
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
list: [1,2,3,4],
current: 1
};
}
handleClick(item) {
this.setState({
current: item
});
}
render() {
return (
<ul>
{this.state.list.map(
(item)=>(
<li className={this.state.current === item ? 'current':''}
onClick={this.handleClick.bind(this, item)}>{item}
</li>
)
)}
</ul>
);
}
}
使用第三种方式,解决方案和第二种基本一致:
//代码7
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
list: [1,2,3,4],
current: 1
};
}
handleClick = (item) => {
this.setState({
current: item
});
}
render() {
return (
<ul>
{this.state.list.map(
(item)=>(
<li className={this.state.current === item ? 'current':''}
onClick={this.handleClick.bind(undefined, item)}>{item}
</li>
)
)}
</ul>
);
}
}
不过这种方式就有点鸡肋了,因为虽然你不需要通过bind函数绑定this,但仍然要使用bind函数来绑定其他参数。
关于事件响应的回调函数,还有一个地方需要注意。不管你在回调函数中有没有显式的声明事件参数Event,React都会把事件Event作为参数传递给回调函数,且参数Event的位置总是在其他自定义参数的后面。例如,在代码6和代码7中,handleClick的参数中虽然没有声明Event参数,但你依然可以通过arguments[1]获取到事件Event对象。
总结
三种绑定事件回调的方式,第一种有额外的性能损失;第二种需要手动绑定this,代码量增多;第三种用到了ES7的特性,目前并非默认支持,需要Babel插件的支持,但是写法最为简洁,也不需要手动绑定this。推荐使用第二种和第三种方式。
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。
# react
# 事件处理
# 事件
# 响应式
# React事件处理的机制及原理
# React学习笔记之事件处理(二)
# React的事件处理你了解吗
# 绑定
# 回调
# 第二种
# 的是
# 第三种
# 推荐使用
# 可以通过
# 需要注意
# 第一种
# 我想
# 就会
# 也不
# 是在
# 也有
# 好了
# 你是
# 相关内容
# 让我们
# 不需要
# 你也
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
北京网站制作的公司有哪些,北京白云观官方网站?
邀请函制作网站有哪些,有没有做年会邀请函的网站啊?在线制作,模板很多的那种?
Laravel DB事务怎么使用_Laravel数据库事务回滚操作
制作网站软件推荐手机版,如何制作属于自己的手机网站app应用?
如何续费美橙建站之星域名及服务?
详解jQuery中的事件
高防服务器租用指南:配置选择与快速部署攻略
大连 网站制作,大连天途有线官网?
如何在万网开始建站?分步指南解析
Laravel Facade的原理是什么_深入理解Laravel门面及其工作机制
如何实现建站之星域名转发设置?
如何用JavaScript实现文本编辑器_光标和选区怎么处理
七夕网站制作视频,七夕大促活动怎么报名?
Laravel如何生成PDF或Excel文件_Laravel文档导出工具与使用教程
Laravel怎么配置S3云存储驱动_Laravel集成阿里云OSS或AWS S3存储桶【教程】
Laravel distinct去重查询_Laravel Eloquent去重方法
高端建站如何打造兼具美学与转化的品牌官网?
详解Nginx + Tomcat 反向代理 如何在高效的在一台服务器部署多个站点
Laravel怎么创建控制器Controller_Laravel路由绑定与控制器逻辑编写【指南】
Windows10怎样连接蓝牙设备_Windows10蓝牙连接步骤【教程】
如何解决hover在ie6中的兼容性问题
大连企业网站制作公司,大连2025企业社保缴费网上缴费流程?
Laravel的辅助函数有哪些_Laravel常用Helpers函数提高开发效率
如何在宝塔面板中创建新站点?
Laravel如何实现模型的全局作用域?(Global Scope示例)
如何自定义建站之星网站的导航菜单样式?
ChatGPT常用指令模板大全 新手快速上手的万能Prompt合集
高防服务器租用如何选择配置与防御等级?
如何在阿里云虚拟机上搭建网站?步骤解析与避坑指南
Laravel请求验证怎么写_Laravel Validator自定义表单验证规则教程
iOS验证手机号的正则表达式
laravel怎么为应用开启和关闭维护模式_laravel应用维护模式开启与关闭方法
晋江文学城电脑版官网 晋江文学城网页版直接进入
laravel怎么为API路由添加签名中间件保护_laravel API路由签名中间件保护方法
Laravel如何使用Socialite实现第三方登录?(微信/GitHub示例)
Python制作简易注册登录系统
JavaScript如何实现音频处理_Web Audio API如何工作?
Laravel中的Facade(门面)到底是什么原理
如何快速生成ASP一键建站模板并优化安全性?
如何在香港服务器上快速搭建免备案网站?
零服务器AI建站解决方案:快速部署与云端平台低成本实践
Laravel如何连接多个数据库_Laravel多数据库连接配置与切换教程
Android使用GridView实现日历的简单功能
如何快速辨别茅台真假?关键步骤解析
网站制作免费,什么网站能看正片电影?
网站制作怎么样才能赚钱,用自己的电脑做服务器架设网站有什么利弊,能赚钱吗?
厦门模型网站设计制作公司,厦门航空飞机模型掉色怎么办?
jQuery validate插件功能与用法详解
HTML透明颜色代码在Angular里怎么设置_Angular透明颜色使用指南【详解】
在centOS 7安装mysql 5.7的详细教程

