在react
中,存在两种事件,一种是合成事件,一种是原生事件。原生事件很好理解,基于dom
的操作是原生事件,那什么是合成事件呢?
我们在react
组件中常见onClick={},这个其实就是合成事件,并且和原生事件onclick
十分相似,看下面的例子
class Test extends Component {
constructor() {
super(arguments);
this.onReactClick.bind(this);
}
componentDidMount() {
const parentDom = ReactDOM.findDOMNode(this);
const childrenDom = parentDom.queneSelector(".button");
childrenDom .addEventListen('click', this.onDomClick, false);
}
onDomClick() { // 事件委托
console.log('Javascript Dom click');
}
onReactClick() { // react合成事件
console.log('React click');
}
render() {
<div>
<button className="button" onClick={this.onReactClick()}>点击</button>
</div>
}
}
在componentDidMount
里对button
进行的操作,就是原生事件,并且原生事件是快于合成事件的。
那么React
合成事件和原生事件的区别在哪呢?仅仅只是使用方式吗?
事实上,React
并不是将click
事件直接绑定在dom
上面,而是采用事件冒泡的形式冒泡到document
上面,然后React
将事件封装给正式的函数处理运行和处理。如果DOM
上绑定了过多的事件处理函数,整个页面响应以及内存占用可能都会受到影响。React
为了避免这类DOM
事件滥用,同时屏蔽底层不同浏览器之间的事件系统差异,实现了一个中间层——SyntheticEvent
。
当用户在为onClick
添加函数时,React
并没有将Click
事件绑定在 DOM
上面。
而是在document
处监听所有支持的事件,当事件发生并冒泡至document
处时,React
将事件内容封装交给中间层SyntheticEvent
(负责所有事件合成)
所以当事件触发的时候,对使用统一的分发函数dispatchEvent
将指定函数执行。
那么对于原生事件呢?React
也提供了完备的生命周期方法,其中componentDidMount
会在组件已经完成安装并且在浏览器中存在真实的 DOM
后调用,此时我们就可以完成原生事件的绑定。但是要注意的是,React
并不会自动管理原生事件,所以需要我们在卸载组件的时候注销掉原生事件。
有两个需要注意的地方:
- 不要将合成事件与原生事件混用
- 通过
e.target
判断来避免
阻止事件冒泡
(1)阻止合成事件间的冒泡,用e.stopPropagation()
;
(2)阻止合成事件与最外层document
上的事件间的冒泡,用e.nativeEvent.stopImmediatePropagation()
;
(3)阻止合成事件与除最外层document
上的原生事件上的冒泡,通过判断e.target
来避免
componentDidMount() {
document.body.addEventListener('click', e => {
if (e.target && e.target.matches('div.code')) {
return;
}
this.setState({ active: false, }); });
}
网友评论