React事件系统整理
事件系统Virtual DOM在内存中是以对象的形式存在,如果想要在这些对象上加事件就会比较简单。React基于Virtual DOM实现了一个合成事件层,我们所定义的事件会接受到一个合成事件对象的实例。不会存在IE浏览器兼容性的问题,同样支持事件冒泡机制。 合成事件绑定方式React事件的绑定方式在写法上与原生HTML事件监听很相似。 <button onClick={this.handleClick}></button> 这个和JavaScript的DOM0级事件很像,但是又有一些不同:HTML的事件需要全部小写的属性名,而且jsx的属性值可以是任何类型。这里是一个函数指针。 <button onclick="handle()"></button> React并不会像DOM0级事件那样将事件处理器直接绑定到DOM上,React仅仅是借鉴了这种写法。 合成事件的实现机制在React底层,主要对合成事件做了两件事情:事件委派和自动绑定。 1. 事件委派React中并不是把事件处理函数绑定到当前DOM上,而是把所有的事件绑定到结构的最外层,使用统一的事件监听器。 2. 自动绑定在React组件中,每个方法的上下文都会指向该组件的实例,即自动绑定this为当前的组件。而且React会对这种引用缓存,以达到CPU和内存的最大优化。
class App extends Component { handleClick(e,arg) { console.log(e,arg) } render() { return <button onClick={this.handleClick.bind(this,'test')}></button> } } 如果只绑定方法,不传递参数,stage0提供一个双冒号语法: class App extends Component { handleClick(e) { console.log(e) } render() { return ( <button onClick{::this.handleClick}></button> ) } }
import React,{Component} from 'react' class App extends Component { constructor(props) { super(props) } handleClick(e) { console.log(e) } render() { return ( <button onClick={this.handleClick}></button> ) } }
class App extends Component { const handleClick = (e) => { console.log(e) } render() { return ( <button onClick={this.handleClick}></button> ) } } 如上集中方法,都能实现在类定义的组件中绑定this上下文的效果。 在React中使用原生事件我们可以在componentDidMount方法中完成原生事件的绑定,此时组件已经安装完成并且在浏览器中存在真实的dom。 class App extends Component { componentDidMount() { this.refs.button.addEventListener('click',e => { this.handleClick() }) } handleClick(e) { console.log(e) } componentWillUnmount() { this.refs.button.removeEventListener('click') } render() { return <button ref='button'></button> } } 在React中使用DOM原生事件时,一定要在组件卸载时手动移除,否则很有可能出现内存泄漏的问题。然而合成事件在内部已经很好的帮我们处理过了。 合成事件与原生事件混用reactEvent.nativeEvent.stopPropagation()只能用于React合成事件系统中,没办法阻止原生事件的冒泡。原生事件阻止冒泡行为可以阻止React合成事件的传播。 React合成事件系统只是原生DOM事件系统的一个子集,它仅仅实现了DOM LEVEL3事件接口,并且统一了浏览器的兼容性问题。 对比合成事件与JavaScript原生事件我们从4个方面来对比React合成事件与JavaScript原生事件。
浏览器原生DOM事件的传播可以分为3个阶段:事件捕获阶段、目标对象本身事件处理程序、事件冒泡阶段。 React合成事件中没有实现事件捕获,仅仅支持事件冒泡机制。 阻止原生事件传播需要使用e.preventDefault(),不过对于不支持的浏览器可以使用e.cancelBubble = true来阻止。React合成事件中使用e.preventDefault()即可。
React合成事件的事件类型是JavaScript原生事件类型的子集。
原生事件绑定的方式如下: 1. <button onclick="alert(1)">btn</button> 2. e.onclick = function() {} 3. e.addEventListener() React事件绑定方式比较简单: <button onClick={this.handle.bind(this)}></button>
原生DOM事件对象在不同浏览器中存在着差异。在低版本的IE浏览器中,只能使用window.event来获取事件对象。React中不存在这些差异,在事件处理函数中可以得到一个合成事件对象。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |