react组件进阶之 事件原理

简介: 在react 中,给组件注册的事件,不是真正的给组件内的div,或者是其他的元素注册的事件,而是通过事件冒泡的形式,最终都是给document注册的事件。(react 16版本),在react17版本上,事件就不是冒泡到document上了,而是在虚拟的根节点中进行注册.

在前文中,我们初步了解了react 的事件的使用方式,并且只是了解到react 的语法和原生的语法很相似。但是真正的事件原理,其实是大不相同的。


React中的事件


这里的事件:React内置的DOM组件中的事件


1. 注册事件


在react 中,给组件注册的事件,不是真正的给组件内的div,或者是其他的元素注册的事件,而是通过事件冒泡的形式,最终都是给document注册的事件。(react 16版本),在react17版本上,事件就不是冒泡到document上了,而是在虚拟的根节点中进行注册.


20210324084819640.png


2. 事件冒泡


1.一些不冒泡的事件,是直接在元素上监听,如input 框中的focus事件

2.一些document上面没有的事件,直接在元素上监听


样例


click 事件是会冒泡的


import React, { PureComponent } from 'react'
export default class TestCompEventPro extends PureComponent {
  handleBtnClick = () => {
    console.log('我是一个按钮被点击了');
  }
  render() {
    return (
      <div>
        <button onClick={this.handleBtnClick}>我是一个按钮</button>
      </div>
    )
  }
}
// 所有的react 组件都是挂载在root这个真实的dom下面。
document.getElementById('root')!.addEventListener('click', ()=> {
  console.log('我注册了一个点击事件');
})


效果


20210319123833239.png


3. React会根据虚拟DOM树的完成事件函数的调用


16版本是在document进行事件处理, 17版本的是在react 的虚拟跟节点完成事件函数的调用。


4. React的事件参数,并非真实的DOM事件参数,是React合成的一个对象,该对象类似于真实DOM的事件参数


1.stopPropagation,阻止事件在虚拟DOM树中冒泡


案列


import React, { MouseEvent, PureComponent } from 'react'
export default class TestCompEventPro extends PureComponent {
  handleBtnClick = () => {
  }
  render() {
    return (
      <div>
        <button onClick={(e:MouseEvent<HTMLButtonElement>) => {
          console.log('我是一个按钮被点击了');
          e.nativeEvent.stopPropagation();
          e.stopPropagation();
        }}>我是一个按钮</button>
      </div>
    )
  }
}
// 根节点
 <div onClick={(e: React.MouseEvent) => {
        console.log('阻止事件');
      }}>


结果:


20210324091733148.png


2.nativeEvent,可以得到真实的DOM事件对象


案列


 render() {
    return (
      <div>
        <button onClick={(e:MouseEvent<HTMLButtonElement>) => {
          console.log('我是一个按钮被点击了');
         console.log( e.nativeEvent)
        }}>我是一个按钮</button>
      </div>
    )
  }


结果:


20210324091911776.png


4.为了提高执行效率,16版本React使用事件对象池来处理事件对象,在17版本中,这个事件池被移除了


注意事项


1.16版本,如果给真实的DOM注册事件,stopPropagation阻止了事件冒泡,则会导致react的相应事件无法触发,17版本中 需要使用 stopImmediatePropagation


2.如果给真实的DOM注册事件,事件会先于React事件运行,


3.通过React的事件中阻止事件冒泡,无法阻止真实的DOM事件冒泡


4.可以通过nativeEvent.stopImmediatePropagation(),阻止document上剩余事件的执行


5.在事件处理程序中,不要异步的使用事件对象,如果一定要使用,需要调用persist函数(16版本),17版本中这个函数没有实际意义了

相关文章
|
22天前
|
移动开发 前端开发 JavaScript
React 表单与事件
10月更文挑战第10天
30 1
|
6天前
|
前端开发 JavaScript 开发者
React 事件处理机制详解
【10月更文挑战第23天】本文介绍了 React 的事件处理机制,包括事件绑定、事件对象、常见问题及解决方案。通过基础概念和代码示例,详细讲解了如何处理 `this` 绑定、性能优化、阻止默认行为和事件委托等问题,帮助开发者编写高效、可维护的 React 应用程序。
35 4
|
24天前
|
前端开发 JavaScript IDE
React 事件处理
10月更文挑战第8天
17 1
|
1月前
|
存储 前端开发 测试技术
React Hooks 的工作原理
【10月更文挑战第1天】
|
24天前
|
前端开发 JavaScript
一文详解React事件中this指向,面试必备
一文详解React事件中this指向,面试必备
39 0
|
2月前
|
前端开发 JavaScript
react学习(19)事件处理
react学习(19)事件处理
|
2月前
|
前端开发 JavaScript
React的事件与原生事件的执行顺序?
React的事件与原生事件的执行顺序?
|
3月前
|
前端开发 JavaScript Java
React 中的合成事件
【8月更文挑战第30天】
44 6
|
3月前
|
开发者 安全 UED
JSF事件监听器:解锁动态界面的秘密武器,你真的知道如何驾驭它吗?
【8月更文挑战第31天】在构建动态用户界面时,事件监听器是实现组件间通信和响应用户操作的关键机制。JavaServer Faces (JSF) 提供了完整的事件模型,通过自定义事件监听器扩展组件行为。本文详细介绍如何在 JSF 应用中创建和使用事件监听器,提升应用的交互性和响应能力。
34 0
|
3月前
|
前端开发 Java UED
瞬间变身高手!JSF 与 Ajax 强强联手,打造极致用户体验的富客户端应用,让你的应用焕然一新!
【8月更文挑战第31天】JavaServer Faces (JSF) 是 Java EE 标准的一部分,常用于构建企业级 Web 应用。传统 JSF 应用采用全页面刷新方式,可能影响用户体验。通过集成 Ajax 技术,可以显著提升应用的响应速度和交互性。本文详细介绍如何在 JSF 应用中使用 Ajax 构建富客户端应用,并通过具体示例展示 Ajax 在 JSF 中的应用。首先,确保安装 JDK 和支持 Java EE 的应用服务器(如 Apache Tomcat 或 WildFly)。
41 0