内容简介:可以看到 React 里面绑定事件的方式和在 HTML 中绑定事件类似,使用驼峰式命名指定要绑定的 onClick 属性为组件定义的一个方法 {this.handleClick.bind(this)}。注意要显式调用 bind(this) 将事件函数上下文绑定要组件实例上,这也是 React 推崇的原则:没有黑科技,尽量使用显式的容易理解的 JavaScript 代码。“合成事件”会以事件委托(event delegation)的方式绑定到组件最上层,并且在组件卸载(unmount)的时候自动销毁绑定的事件
import React, { Component } from 'react'; import { render } from 'react-dom'; class LikeButton extends Component { constructor(props) { super(props); this.state = { liked: false }; } handleClick(e) { this.setState({ liked: !this.state.liked }); } render() { const text = this.state.liked ? 'like' : 'haven\'t liked'; return ( <p onClick={this.handleClick.bind(this)}> You {text} this. Click to toggle. </p> ); } } render( <LikeButton />, document.getElementById('example') ); 复制代码
可以看到 React 里面绑定事件的方式和在 HTML 中绑定事件类似,使用驼峰式命名指定要绑定的 onClick 属性为组件定义的一个方法 {this.handleClick.bind(this)}。
注意要显式调用 bind(this) 将事件函数上下文绑定要组件实例上,这也是 React 推崇的原则:没有黑科技,尽量使用显式的容易理解的 JavaScript 代码。
2、'合成事件'和 '原生事件'
-
React 实现了一个“合成事件”层(synthetic event system),这个事件模型保证了和 W3C 标准保持一致,所以不用担心有什么诡异的用法,并且这个事件层消除了 IE 与 W3C 标准实现之间的兼容问题。
- “合成事件”还提供了额外的好处:
2.1 事件委托
- 事件委托就是利用事件冒泡原理,把处理任务委托给父元素或者祖先元素(通常用父元素),我们通过目标对象来判断事件源,并执行事件处理。
“合成事件”会以事件委托(event delegation)的方式绑定到组件最上层,并且在组件卸载(unmount)的时候自动销毁绑定的事件。
2.2 原生事件
比如你在 componentDidMount 方法里面通过 addEventListener 绑定的事件就是浏览器原生事件。
使用原生事件的时候注意在 componentWillUnmount 解除绑定 removeEventListener。
Waring:如果不在组件销毁的时候解除事件的话,会造成内存泄露的问题。
怎么解决这个问题?这里可以看我的相关文章 react 内存泄露常见问题解决方案
所有通过 JSX 这种方式绑定的事件都是绑定到“合成事件”,除非你有特别的理由,建议总是用 React 的方式处理事件。
3、事件绑定的几种方法
- 由于类的方法默认不会绑定this,因此在调用的时候如果忘记绑定,this的值将会是undefined。 通常如果不是直接调用,应该为方法绑定this。绑定方式有以下几种:
3.1、 在构造函数中使用bind绑定this
class Button extends React.Component { constructor(props) { super(props); this.handleClick = this.handleClick.bind(this); } handleClick(){ console.log('this is:', this); } render() { return ( <button onClick={this.handleClick}> Click me </button> ); } } 复制代码
3.2、在调用的时候使用 bind 去绑定 this
class Button extends React.Component { handleClick(){ console.log('this is:', this); } render() { return ( <button onClick={this.handleClick.bind(this)}> Click me </button> ); } } 复制代码
3.3、调用的时候使用箭头函数绑定 this
class Button extends React.Component { handleClick(){ console.log('this is:', this); } render() { return ( <button onClick={()=>this.handleClick()}> Click me </button> ); } } 复制代码
3.4、使用属性初始化语法直接绑定
class Button extends React.Component { handleClick=()=>{ console.log('this is:', this); } render() { return ( <button onClick={this.handleClick}> Click me </button> ); } } 复制代码
3.5、比较上诉几个方式的优劣
- 3.2和 3.3 方法都是调用的时候再绑定 this
- 优点 : 写法简单,组件中没有 state 的时候不需要添加构造函数来绑定 this
- 缺点 : 每一次调用的时候都会生成一个新的方法实例,因此对性能有影响,并且当这个函数作为属性值传入低阶组件的时候,这些组件可能会进行额外的重新渲染,因为每一次都是新的方法实例作为的新的属性传递。
- 3.1 方法在构造函数中绑定了 this,调用的时候不需要二次绑定
- 优点 :只会生成一个方法实例,并且绑定一次之后如果多次用到这个方法也不需要绑定了。
- 缺点 :即使不适用 state 的时候也需要在构造函数中绑定 this,代码量多。
- 3.4 方法 利用属性初始化语法,将方法初始化为箭头函数,因此在创建函数的时候就绑定了this。
- 优点 :创建方法就绑定this,不需要在类构造函数中绑定,调用的时候不需要再作绑定。结合了方式1、方式2、方式3的优点
- 缺点 :以前有需要 babel 转移的需求,现在随着性能越来越好,也会考虑这一点消耗的问。
3.6 怎么传参?
- 给事件处理函数传递额外参数的方式:bind(this, arg1, arg2, ...)
- 非 bind 的直接传参就可以了。
render: function() { return <p onClick={this.handleClick.bind(this, 'extra param')}>; }, handleClick: function(param, event) { // handle click } 复制代码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Golang Echo数据绑定中time.Time类型绑定失败
- 如何在Symfony的表单中添加一个未绑定字段,否则绑定到一个实体?
- js双向绑定
- 延迟静态绑定——static
- 绑定自定义事件
- angular组件双向绑定
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
高性能JavaScript
【美】Nicholas C. Zakas(尼古拉斯.泽卡斯) / 丁琛 / 电子工业出版社 / 2015-8-1 / 65
如果你使用 JavaScript 构建交互丰富的 Web 应用,那么 JavaScript 代码可能是造成你的Web应用速度变慢的主要原因。《高性能JavaScript》揭示的技术和策略能帮助你在开发过程中消除性能瓶颈。你将会了解如何提升各方面的性能,包括代码的加载、运行、DOM 交互、页面生存周期等。雅虎的前端工程师 Nicholas C. Zakas 和其他五位 JavaScript 专家介绍......一起来看看 《高性能JavaScript》 这本书的介绍吧!