持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第5天,点击查看活动详情
核心描述
- 原生事件:在 componentDidMount生命周期里边进行addEventListener绑定的事件
- 合成事件:通过 JSX 方式绑定的事件,比如
onClick={() => this.handle()}
- React 使用合成事件的原因:
- 抹平不同浏览器 API 的差异,更便于跨平台
- 事件合成可以处理兼容性问题
- 利用事件委托机制,支持动态绑定,简化了 DOM 事件处理逻辑,减少了内存开销
- React 16 正式版本之后引入 Fiber 架构,React 可以通过干预事件的分发以优化用户的交互体验
知识拓展
-
合成事件的特点:
- React 上注册的事件最终会绑定在 document 这个 DOM 上,而不是 React 组件对应的 DOM(减少内存开销就是因为所有的事件都绑定在 document 上,其他节点没有绑定事件)
- React 自身实现了一套事件冒泡机制,所以这也就是为什么我们 event.stopPropagation() 无效的原因
- React 通过队列的形式,从触发的组件向父组件回溯,然后调用他们 JSX 中定义的 callback
- React 有一套自己的合成事件 SyntheticEvent,不是原生的,这个可以自己去看官网
- React 通过对象池的形式管理合成事件对象的创建和销毁,减少了垃圾的生成和新对象内存的分配,提高了性能
-
React 17 不在向 document 附加事件处理器,而是放到了渲染 React 树的根 DOM 容器上。
-
React 16 中,事件由事件池维护,本意是为了提高性能,但反而引发了一些歧义,让开发者出现各种 bug,所以在 React 17 中移除
// react 16 中,如果要在事件中获取事件对象的属性,需要调用 e.persist() ,否则会出错
function handleChange(e){
// 如果没有这句,会报错
e.persist()
setTimeout(()=>{
console.log(e.target.value)
})
}
参考资料
- React 文档-合成事件:zh-hans.reactjs.org/docs/events…
- 由浅到深的React合成事件:juejin.cn/post/684490…
浏览知识共享许可协议
本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。