React 为什么要自己实现一套事件系统 ? React的事件系统是怎么运作起来的?
一个例子
从一个例子开始,这样记忆深刻。
class App extends React.Component {
innerClick = e => {
console.log("A: react inner click.");
// e.stopPropagation();
};
outerClick = () => {
console.log("B: react outer click.");
};
componentDidMount() {
document
.getElementById("outer")
.addEventListener("click", () => console.log("C: native outer click"));
window.addEventListener("click", () =>
console.log("D: native window click")
);
}
render() {
return (
<div id="outer" onClick={this.outerClick}>
<button id="inner" onClick={this.innerClick}>
BUTTON
</button>
</div>
);
}
}
根据例子代码,来推测一下 输出顺序是什么。
如果把第四行的 stopPropagation
注释放开结果又是什么。
正确答案是:
C -> A -> B -> D
另外是: C -> A
React为什么要自己实现一个事件系统
主要是性能和复用两个方面。 来图
首先对于性能来说,React作为一套View层面的框架,通过渲染得到vDOM,再由diff算法决定DOM树那些结点需要新增、替换或修改,假如直接在DOM结点插入原生事件监听,则会导致频繁的调用addEventListener和removeEventListener,造成性能的浪费。所以React采用了事件代理的方法,对于大部分事件而言都在document上做监听,然后根据Event中的target来判断事件触发的结点。
而对于复用来说,React看到在不同的浏览器和平台上,用户界面上的事件其实非常相似,例如普通的click,change等等。React希望通过封装一层事件系统,将不同平台的原生事件都封装成SyntheticEvent
React更进一步,帮我们统一了不同平台的兼容,使我们在开发的时候只需要考虑标准化的事件即可。
重要总结
其实看了本文,只想让你明白对React
事件系统有个简单的认识。知道“为什么React需要自己实现一套事件系统?”和“React的事件系统是怎么运作起来的?”。React
为了性能和复用,采用了事件代理,池,批量更新,跨浏览器和跨平台兼容等思想,将事件监听挂载在document
上,并且构造合成事件,并且在内部模拟了一套捕获和冒泡并触发回调函数的机制,实现了自己一套事件系统。
本文只是很浅很浅的说了一下,便于查找。
对于复用这块,React
还使用了池的概念。
React
合成的SyntheticEvent
采用了池的思想,从而达到节约内存,避免频繁的创建和销毁事件对象的目的。
可以查看这篇文章了解更详细的内容