事件系统
Virtual DOM在内存中是以对象的形式存在的,如果想要在这些对象上添加事件的话,React是基于Virtual DOM实现了一个合成事件层,他完全符合w3c标准,不存在ie的兼容问题。并且拥有和浏览器原生事件一样的接口,支持冒泡,可以使用stopPropagation()和preventDefault()来中断它。好吧不要想太多记住就是和浏览器事件一样,处了调用形式
合成事件的绑定方式
简单的很
//jsx: <button onClick={this.handleClick}>按钮</button> //浏览器原生: <button onclick="handleClick()">按钮</button>
react只是借鉴DOM0级事件的这种写法
绑定方法
在react组件中,每个方法的上下文都会指向该组件的实例,即自动绑定this为当前组件。而且React还会对这种引用进行缓存,以达到cpu和内存的最优化。在使用ES6 class或者纯粹函数时,这种绑定就不复存在了,我们需要手动实现this绑定
bind方法
这个方法可以帮助我们绑定事件处理器内的this,并且可以向事件处理器中传递参数
import React,{ Component } form 'react'; class App extends Component { handleClick (e,arg) { console.log(e,arg) } render () { return ( <button onClick={this.handleClick.bind(this,'test')}>按钮</button> ) } }
构造器内声明
在组件的构造器内完成了this的绑定,这种绑定方式的好处在于仅需要进行一次绑定,而不需要每次调用事件监听器时去执行绑定操作。
import React,{ Component } form 'react'; class App extends Component { constructor () { super(); this.handleClick = this.handleClick.bind(this,arg); } handleClick (e,arg) } render () { return ( <button onClick={this.handleClick(this,'test')}>按钮</button> ) } }
箭头函数
箭头函数不仅是函数的语法糖,它还自动绑定定义此函数作用域的this,因此我们不需要对它使用bind方法。
import React,{ Component } form 'react'; class App extends Component { constructor () { super(); this.handleClick = (e,arg) => { console.log(e,arg) } } render () { return ( <button onClick={this.handleClick(this,'test')}>按钮</button> ) } }
React中使用原生事件
React中提供了很好的合成事件系统,但有时候也需要用到原生事件。在React生命周期中提供了componentDidMount会在组件已经完成安装并且在浏览器中存在真实的DOM后调用,此时我们就可以完成原生事件的绑定。比如:
import React,{ Component } form 'react'; class App extends Component { constructor () { super(); } componentDidMount () { this.refs.button.addEventListener('click',e => { handleClick(e); }) } handleClick (e) { console.log(e) } componentWillUnmount () { this.refs.button.removeEventListener('click') } render () { return ( <button ref="button">按钮</button> ) } }@H_404_42@
一定要注意在React中使用原生DOM事件时,一定要在组件卸载时手动移除,否则很可能出现内存泄漏的问题。2而使用合成事件系统时则不需要,因为React内部以及处理了。