Open yaofly2012 opened 4 years ago
SyntheticEvent
对象为了提升性能,React会复用SyntheticEvent
对象,即事件回调函数的实参是同一个对象(但属性值可能不一样)
let eventObj = false;
function dispalyProps(obj) {
Object.keys(obj).forEach(key => {
console.log(`${key}=${obj[key]}`)
})
}
class Index extends React.Component {
handleClick = (e) => {
if(eventObj === false) {
eventObj = e;
}
console.log(e === eventObj) // true
dispalyProps(e)
setTimeout(() => {
dispalyProps(e)
}, 0)
}
handleTouchEnd = (e) => {
console.log(e === eventObj) // false
}
render() {
return (
<div>
<h2 onTouchEnd={this.handleTouchEnd}>SynthenticEvent</h2>
<ul>
<li onClick={this.handleClick}>Event System</li>
<li onClick={this.handleClick}>Event Pool</li>
</ul>
</div>
)
}
}
export default Index;
nullified
(数据属性),即被重置为null
;
这也导致不能在异步操作里访问事件对象(属性都为null了),也不要持久化事件对象后续使用。SyntheticEvent
对象的,即相同的事件类型的事件处理函数的实参一样。SynthenicEvent
对象创建比较耗时,得看源码了?调用e.persist
方法可以让React不缓存当前SyntheticEvent
对象:
SyntheticEvent
对象进行nullify
,这样可以在异步操作里可以正确访问事件对象;
let eventObj = false;
function dispalyProps(obj) {
Object.keys(obj).forEach(key => {
console.log(${key}=${obj[key]}
)
})
}
class Index extends React.Component {
handleClick = (e) => {
if(eventObj === false) {
eventObj = e;
} else {
console.log(e === eventObj) // false,每次都是新对象
}
e.persist(); // 脱离事件池
dispalyProps(e)
setTimeout(() => {
dispalyProps(e)
}, 0)
}
handleTouchEnd = (e) => {
console.log(e === eventObj) // false
}
render() {
return (
<div>
<h2 onClick={this.handleTouchEnd}>SynthenticEvent</h2>
<ul>
<li onClick={this.handleClick}>Event System</li>
<li onClick={this.handleClick}>Event Pool</li>
</ul>
</div>
)
}
}
export default Index;
# 二、参考
1. [React API SynthenicEvent](https://reactjs.org/docs/events.html)
2. [What is event pooling in react?](https://stackoverflow.com/questions/36114196/what-is-event-pooling-in-react)
3. [Medium ReactJS Events: “Pooling”, “Nullification”, & event.persist()](https://medium.com/@brunogarciagonzalez/reactjs-events-exploration-a295505016f1)
React17之后移除事件池了
一、概念:
二、Event System
React内部实现了自己的事件系统,磨平各浏览器的差异,提供统一且和DOM Event一致的访问API。
2.1 事件的捕获阶段和冒泡阶段
e.stopPropagation
方法可以阻止捕获和冒泡阶段中当前事件的进一步传播。eventPhase
始终是3; 说明React是借助DOM的冒泡事件处理React捕获阶段事件处理函数的。2.2 绑定捕获阶段事件处理函数
事件处理函数默认在冒泡阶段触发,在事件名称添加后缀
Capture
表示绑定捕获阶段事件处理函数。2.3 Focus Event
这句话是指所有的React元素都可以绑定
focus
,blur
事件。但注意并不是说所有React元素都会触发focus
,blur
事件。focus
,blur
事件不一样的是React DOMfocus
,blur
事件会进行冒泡; 行为跟focusin
,focusout
类似了。relatedTarget
的取值逻辑跟DOM FocusEvent.relatedTarget一样.class Index extends React.Component { handleFocus = (e) => { console.log(
focus:\tcurrentTarget#${e.currentTarget.id}\ttarget#${e.target.id}\t relatedTarget#${e.relatedTarget ? e.relatedTarget.id : 'null'}
) } handleBlur = (e) => { console.log(blur:\tctcurrentTarget#${e.currentTarget.id}\ttarget#${e.target.id}\t relatedTarget#${e.relatedTarget ? e.relatedTarget.id : 'null'}
) }}
export default Index;