当前位置: 首页 > article >正文

React合成事件及其核心思想详解

相关联Javascript知识

1.JavaScript 的事件流

   事件流是 JavaScript 处理事件的机制,它描述了事件从发生到被处理的过程。事件流主要包括两个阶段:捕获阶段和冒泡阶段。在捕获阶段,事件从文档的根元素开始,逐层向下传播到目标元素,这个阶段可以阻止事件到达目标元素。在冒泡阶段,事件从目标元素开始,逐层向上传播到文档的根元素,这个阶段可以对事件进行响应。事件流的顺序是:捕获处理程序 → 目标处理程序 → 冒泡处理程序。

2.JavaScript 事件冒泡和捕获的区别是什么?默认是冒泡还是捕获?
  • 区别:

     事件冒泡:事件从目标元素开始,逐层向上传播到祖先元素,直到文档的根元素(在浏览器中通常是 document 对象)。
     事件捕获:事件从文档的根元素开始,逐层向下传播到目标元素。

  • 默认行为:

在 JavaScript 中,事件默认是按照冒泡阶段进行传播的。但是,可以通过在事件监听器中使用 capture 选项或 addEventListener 方法第三个参数来指定事件在捕获阶段进行传播。

3.什么是 JavaScript 的事件代理?

      事件代理(Event Delegation)是一种常用的技术,它利用事件冒泡的原理,将事件监听器添加到父元素上,而不是直接添加到目标元素上。当目标元素触发事件时,事件会冒泡到父元素,父元素上的事件监听器可以捕获并处理该事件。这种方法可以减少事件监听器的数量,提高性能,并且便于管理事件监听器。

1. 什么是合成事件?

React 的合成事件 (SyntheticEvent) 是对原生 DOM 事件的封装,它在所有浏览器中表现一致,用于解决跨浏览器的兼容性问题。它是 React 自身实现的一个轻量级事件系统。

2. 核心思想

React 合成事件的核心思想主要包括以下几个方面:

a. 跨浏览器的兼容性

合成事件对原生事件进行了统一封装,屏蔽了不同浏览器之间的行为差异。开发者可以直接使用 React 提供的合成事件,而无需考虑浏览器特性。

b. 事件委托 (Event Delegation)

React 并不将事件处理程序绑定到每个具体的 DOM 节点,而是利用事件委托的机制,将所有事件统一绑定到根节点上(如 documentcontainer)。当事件发生时,React 会根据事件对象的 target 属性找到对应的组件进行处理。

优点:

  • 减少了事件绑定的数量,提升了性能,尤其是在大量动态 DOM 节点的场景中。
  • 易于统一管理和清理事件监听器
c. 事件池 (Event Pool)

为了提高性能,React 会对事件对象进行对象池化处理。合成事件对象会被重用,事件处理结束后,合成事件的所有属性都会被清空。

function handleClick(event) {
  console.log(event.type); // 可以正常访问
  setTimeout(() => {
    console.log(event.type); // 此时访问将为空,因为事件对象已被复用
  }, 0);
}

如果需要异步访问事件对象,可以通过 event.persist() 方法保留事件。

function handleClick(event) {
  event.persist();
  setTimeout(() => {
    console.log(event.type); // 异步访问仍然可用
  }, 0);
}
3. 合成事件与原生事件的对比
特性React 合成事件原生 JavaScript 事件
兼容性跨浏览器统一表现需要处理浏览器差异
事件绑定事件委托到根节点直接绑定到具体 DOM 节点
性能减少事件监听器数量每个绑定的 DOM 节点都有独立监听器
API统一接口(如 onClick, onChange浏览器原生 API
事件复用事件池机制,需调用 persist()不存在复用机制

4. 常见的合成事件

React 提供了一组封装的合成事件,常见事件包括:

  • 鼠标事件: onClick, onDoubleClick, onMouseEnter, onMouseLeave
  • 键盘事件: onKeyDown, onKeyPress, onKeyUp
  • 表单事件: onChange, onInput, onSubmit
  • 焦点事件: onFocus, onBlur
  • 触摸事件: onTouchStart, onTouchMove, onTouchEnd
  • 其他: onScroll, onWheel, onDrag, onDrop
5. 示例代码
import React from "react";

function App() {
  const handleClick = (event) => {
    console.log("Button clicked!");
    console.log("Event type:", event.type);
    event.persist(); // 保留事件
    setTimeout(() => {
      console.log("Event type after timeout:", event.type); // 仍可访问
    }, 1000);
  };

  return <button onClick={handleClick}>Click Me</button>;
}

export default App;
6. 为什么合成事件更高效?
  1. 事件委托减少了大量的事件监听器开销。
  2. 对象池机制复用事件对象,避免频繁创建和销毁,提高了内存使用效率。
  3. 批量更新:合成事件结合 React 的更新机制(如事务机制、批处理),可以避免不必要的多次重绘。
7. 原生事件与合成事件的混用

在某些情况下,可能需要使用原生事件(如性能优化、与第三方库兼容)。React 合成事件和原生事件可以共存,但需注意它们是独立的事件系统。

function App() {
  React.useEffect(() => {
    const handleNativeClick = () => console.log("Native click");
    document.getElementById("btn").addEventListener("click", handleNativeClick);

    return () => {
      document.getElementById("btn").removeEventListener("click", handleNativeClick);
    };
  }, []);

  return <button id="btn">Click Me</button>;
}
总结

React 的合成事件通过事件委托和事件池机制,在保证跨浏览器一致性的同时,优化了性能。虽然它与原生事件有区别,但它简化了开发流程,是 React 框架设计的重要组成部分。

------------------------------------------------------------------------------------------------------------------------------

callBack

React合成事件是React模拟原生DOM事件所有能力的一个事件对象,它是React中较为重要的概念。以下是对React合成事件的详细解析:

一、合成事件的概念

React合成事件(SyntheticEvent)是React根据W3C规范定义的事件,它兼容所有浏览器,并提供了与浏览器原生事件相同的接口。在React中,所有事件都是合成的,而不是原生DOM事件。但可以通过e.nativeEvent属性获取原生DOM事件。

二、合成事件的作用

  1. 浏览器兼容:React提供的合成事件用来抹平不同浏览器事件对象之间的差异,将不同平台事件模拟成合成事件。
  2. 性能优化:React采用顶层事件代理机制,将所有事件绑定在document上,通过dispatchEvent来分发事件。这种处理减少了事件注册的次数,并提高了性能。同时,React还引入了事件池来复用事件对象,避免频繁地创建和销毁事件对象(垃圾回收)。
  3. 统一事件管理:合成事件使得React能够统一管理和处理事件,简化了事件处理的逻辑。

三、合成事件与原生事件的区别

  1. 命名方式

    • 原生事件:命名为纯小写,如onclickonblur等。
    • React事件:命名采用小驼峰式(camelCase),如onClickonBlur等。
  2. 事件处理函数写法

    • 原生事件:事件处理函数为字符串。
    • React事件:在JSX语法中,传入一个函数作为事件处理函数。
  3. 阻止默认行为

    • 原生事件:可以通过返回false方式来阻止默认行为。
    • React事件:需要显式使用preventDefault()方法来阻止默认行为。
  4. 事件传播

    • 原生事件:执行需要经过三个阶段:捕获阶段、目标元素阶段、冒泡阶段。节点上的原生事件的执行是在目标阶段。
    • 合成事件:执行是在冒泡阶段。所以原生事件会先合成事件执行,然后再往父节点冒泡。原生事件阻止冒泡会阻止合成事件的触发,而合成事件的阻止冒泡不会影响原生事件。

四、合成事件的使用

在React中,可以使用onEventName属性为元素添加事件侦听器,其中eventName是要侦听的事件的名称(例如onClickonMouseMove)。事件侦听器函数将接收一个合成事件对象作为参数。

jsx复制代码

function handleClick(event) {
console.log('Button was clicked!');
}
return <button onClick={handleClick}>Click me</button>;

合成事件对象提供了多个有用的属性,如type(事件类型)、target(触发事件的DOM元素)、currentTarget(正在处理事件的DOM元素,通常与target相同,但对于冒泡事件则不同)等。此外,还包含了阻止默认行为的方法,例如preventDefault()stopPropagation()

五、合成事件的常见问题

  1. 事件池:React使用事件池来复用事件对象。当事件触发时,React会从事件池中获取一个事件对象,并在事件处理完成后将其释放回事件池。这避免了频繁地创建和销毁事件对象,提高了性能。
  2. 事件委托:React采用事件委托的方式来处理事件。它将事件侦听器附加到父元素上,而不是为每个子元素附加单独的侦听器。这可以提高性能,特别是对于具有大量子元素的列表或网格。
  3. 阻止事件冒泡:在React中,可以使用stopPropagation()方法来阻止事件冒泡。但需要注意的是,阻止合成事件的冒泡不会影响原生事件的传播。
  4. 异步操作中的事件对象:由于合成事件对象在事件处理函数调用后被回收,因此应避免在异步操作中访问这些对象。如果需要在异步操作中使用事件对象的信息,应该在事件处理函数内部将其保存到另一个变量中。

六、最佳实践

  1. 使用箭头函数作为事件处理程序:这有助于绑定事件处理程序函数中的this上下文。但需要注意的是,使用箭头函数会在每次渲染时创建一个新的函数实例,这可能会影响性能。在性能敏感的场合,可以考虑使用其他方法来绑定this上下文。
  2. 使用事件委派来提高性能:对于具有大量子元素的列表或网格,将事件侦听器附加到父元素上可以提高性能。
  3. 小心使用preventDefault()stopPropagation():仅在绝对必要时使用这些方法,因为它们可以中断默认浏览器行为并影响事件传播。

综上所述,React合成事件是React中处理事件的一种重要机制。它提供了跨浏览器兼容性、性能优化和统一事件管理等优点。在使用合成事件时,需要遵循最佳实践并注意常见问题以确保代码的正确性和性能。

 


http://www.kler.cn/a/401552.html

相关文章:

  • C 语言标准库 - <stdlib.h>
  • LLM评测指标与评测方法
  • 【FAQ】HarmonyOS SDK 闭源开放能力 —Share Kit
  • Django5 2024全栈开发指南(三):数据库模型与ORM操作
  • 极速入门数模电路
  • .NET桌面应用架构Demo与实战|WPF+MVVM+EFCore+IOC+DI+Code First+AutoMapper
  • 强化学习数学原理学习(四)
  • Ubuntu安装配置MySQL(远程登录)
  • 网络基础(4)IP协议
  • tdengine学习笔记实战-jdbc连接tdengine数据库
  • SHELL(5)字符串运算符和逻辑运算符
  • QT与嵌入式——获取网络实时时间
  • 一个交替优化问题的求解(续)
  • GNN初探
  • 2.tree of thought (使用LangChain解决N皇后问题)
  • 机器学习笔记 // 创建并训练DNN来拟合和预测序列数据
  • 运维面试题.云计算面试题之四.K8S
  • MFC线程-AfxBeginThread使用方法
  • SpringBoot常用的注解
  • 源码分析Spring Boot (v3.3.0)
  • Linux离线安装python相关包
  • driver.js实现页面操作指引
  • Linux-Samba
  • Axios交互
  • 疫情下的图书馆管理系统开发:Spring Boot
  • MATLAB调用Python自定义函数,极度方便好用