前言

本文主要给大家介绍的是关于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的事件处理你了解吗
# 绑定
# 回调
# 第二种
# 的是
# 第三种
# 推荐使用
# 可以通过
# 需要注意
# 第一种
# 我想
# 就会
# 也不
# 是在
# 也有
# 好了
# 你是
# 相关内容
# 让我们
# 不需要
# 你也
相关文章:
电影网站制作价格表,那些提供免费电影的网站,他们是怎么盈利的?
建站主机解析:虚拟主机配置与服务器选择指南
建站之星CMS五站合一模板配置与SEO优化指南
,交易猫的商品怎么发布到网站上去?
如何快速生成凡客建站的专业级图册?
已有域名和空间,如何快速搭建网站?
宝塔建站无法访问?如何排查配置与端口问题?
常州自助建站:操作简便模板丰富,企业个人快速搭建网站
装修招标网站设计制作流程,装修招标流程?
北京专业网站制作设计师招聘,北京白云观官方网站?
,想在网上投简历,哪几个网站比较好?
合肥制作网站的公司有哪些,合肥聚美网络科技有限公司介绍?
如何通过商城自助建站源码实现零基础高效建站?
购物网站制作公司有哪些,哪个购物网站比较好?
建站org新手必看:2024最新搭建流程与模板选择技巧
Swift中swift中的switch 语句
南阳网站制作公司推荐,小学电子版试卷去哪里找资源好?
台州网站建设制作公司,浙江手机无犯罪记录证明怎么开?
购物网站制作费用多少,开办网上购物网站,需要办理哪些手续?
非常酷的网站设计制作软件,酷培ai教育官方网站?
建站之星后台密码遗忘?如何快速找回?
如何通过建站之星自助学习解决操作问题?
如何在七牛云存储上搭建网站并设置自定义域名?
PHP 500报错的快速解决方法
商务网站制作工程师,从哪几个方面把握电子商务网站主页和页面的特色设计?
大学网站设计制作软件有哪些,如何将网站制作成自己app?
学校建站服务器如何选型才能满足性能需求?
PHP正则匹配日期和时间(时间戳转换)的实例代码
建站之星后台密码如何安全设置与找回?
如何用AWS免费套餐快速搭建高效网站?
如何选择最佳自助建站系统?快速指南解析优劣
南京网站制作费用,南京远驱官方网站?
制作旅游网站html,怎样注册旅游网站?
如何快速查询网站的真实建站时间?
如何确认建站备案号应放置的具体位置?
义乌企业网站制作公司,请问义乌比较好的批发小商品的网站是什么?
制作ppt免费网站有哪些,有哪些比较好的ppt模板下载网站?
如何选择高效便捷的WAP商城建站系统?
免费的流程图制作网站有哪些,2025年教师初级职称申报网上流程?
青岛网站建设如何选择本地服务器?
如何快速重置建站主机并恢复默认配置?
学校为何禁止电信移动建设网站?
网页设计与网站制作内容,怎样注册网站?
公司门户网站制作流程,华为官网怎么做?
杭州银行网站设计制作流程,杭州银行怎么开通认证方式?
如何基于PHP生成高效IDC网络公司建站源码?
网站制作新手教程,新手建设一个网站需要注意些什么?
网站制作报价单模板图片,小松挖机官方网站报价?
建站10G流量真的够用吗?如何应对访问高峰?
网站图片在线制作软件,怎么在图片上做链接?
*请认真填写需求信息,我们会在24小时内与您取得联系。