广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >React合成事件原理解析
  • 675
分享到

React合成事件原理解析

2024-04-02 19:04:59 675人浏览 安东尼
摘要

目录事件介绍什么是事件?举个栗子代码实现React合成事件基础知识什么是合成事件?在React中事件的写法和原生事件写法的区别?为什么会有合成事件?合成事件机制简述React合成事件

事件介绍

什么是事件?

事件是在编程时系统内发生的动作或者发生的事情,而开发者可以某种方式对事件做出回应,而这里有几个先决条件

  • 事件对象
  • 给事件对象注册事件,当事件被触发后需要做什么
  • 事件触发

举个栗子

?在机场等待检票,听到广播后排队检票

  • 事件对象,也就是检票事件
  • 事件注册/监听,也就是我们在机场等待的时候
  • 事件触发,广播响起开始检票
  • 事件触发之后的回调,我们开始排队...

代码实现

// 检票事件
var event = new Event('check-ticket');
// 事件注册,并编写回调
elem.addEventListener('check-ticket', function (e) { 
  // 开始排队
  LiningUp()
});
// 事件触发,广播开始检票
elem.dispatchEvent(event);

React合成事件基础知识

什么是合成事件?

不是浏览器本身触发的事件,自己创建和触发的事件。

在React中事件的写法和原生事件写法的区别?

  • React 事件的命名采用小驼峰式(camelCase),而不是纯小写。
  • 使用 jsX 语法时你需要传入一个函数作为事件处理函数,而不是一个字符串
// html中的写法
<button onclick="handleClick()">
  Activate Lasers
</button>
// React中的写法
<button onClick={handleClick}>
  Activate Lasers
</button>

为什么会有合成事件?

  • 对事件进行归类,可以在事件产生的任务上包含不同的优先级
  • 提供合成事件对象,抹平浏览器的兼容性差异

合成事件机制简述

提供了一种“顶层注册,事件收集,统一触发”的事件机制

  • “顶层注册”,其实是在root元素上绑定一个统一的事件处理函数
  • “事件收集”, 事件触发时(实际上是root上的事件处理函数被执行),构造合成事件对象,按照冒泡或捕获的路径去组件中收集真正的事件处理函数
  • “统一触发”,在收集过程之后,对收集的事件逐一执行,并共享同一个合成事件对象

React合成事件实现原理

事件注册

时机:在fiber节点进入render阶段的complete阶段时,名为onClick的props会被识别为事件进行处理

function setInitialDOMProperties(
  tag: string,
  domElement: Element,
  rootContainerElement: Element | Document,
  nextProps: Object,
  isCustomComponentTag: boolean,
): void {
  for (const propKey in nextProps) {
    if (!nextProps.hasOwnProperty(propKey)) {
      ...
    } else if (reGIStrationNameDependencies.hasOwnProperty(propKey)) {
        // 如果propKey属于事件类型,则进行事件绑定
        ensureListeningTo(rootContainerElement, propKey, domElement);
      }
    }
  }
}
// registrationNameDependencies为合成事件名和真实事件的映射,格式如下:
{
  onChange: ['change', 'click', 'focusin', 'focusout', 'input', 'keydown', 'keyup', 'selectionchange']
  onChangeCapture: ['change', 'click', 'focusin', 'focusout', 'input', 'keydown', 'keyup', 'selectionchange']
  onClick: ['click']
}

调用ensureListeningTo进行事件绑定

然后调用DOMPluginEventSystem.js中的addTrappedEventListener进行事件注册,而监听器listener是React通过createEventListenerWrapperWithPriority创建出优先级不同的时间监听包装器

总的来说,会有三种事件监听包装器:

  • dispatchDiscreteEvent: 处理离散事件
  • dispatchUserBlockingUpdate:处理用户阻塞事件
  • dispatchEvent:处理连续事件

事件触发-事件监听器做了什么

负责以不同的优先级权重来触发真正的事件流程

createEventListenerWrapperWithPriority中,根据eventPriority事件优先级不同调用事件dispatchDiscreteEventdispatchUserBlockingUpdatedispatchUserBlockingUpdatedispatchEvent进行事件绑定

export function createEventListenerWrapperWithPriority(
  targetContainer: EventTarget,
  domEventName: DOMEventName,
  eventSystemFlags: EventSystemFlags,
): Function {
  const eventPriority = getEventPriorityForPluginSystem(domEventName);
  let listenerWrapper;
  switch (eventPriority) {
    case DiscreteEvent:
      listenerWrapper = dispatchDiscreteEvent;
      break;
    case UserBlockingEvent:
      listenerWrapper = dispatchUserBlockingUpdate;
      break;
    case ContinuousEvent:
    default:
      listenerWrapper = dispatchEvent;
      break;
  }
  return listenerWrapper.bind(
    null,
    domEventName,
    eventSystemFlags,
    targetContainer,
  );
}

在每一个事件绑定函数中,会调用dispatchEventsForPlugins函数

  • 合成事件,放入dispatchQueue中

    而dispatchQueue由两部分组成

    • 合成事件对象
    • 多个listeners(可以共用一个合成事件对象)
  • 执行事件执行路径下的事件,从dispatchQueue中取出事件对象events和具体执行路径listeners,然后遍历执行

function dispatchEventsForPlugins(
  domEventName: DOMEventName,
  eventSystemFlags: EventSystemFlags,
  nativeEvent: AnyNativeEvent,
  targetInst: null | Fiber,
  targetContainer: EventTarget,
): void {
  const nativeEventTarget = getEventTarget(nativeEvent);
  const dispatchQueue: DispatchQueue = [];
  // 通过不同事件类型插件进行事件对象合成,将合成事件放入事件队列中:dispatchQueue中
  extractEvents(
    dispatchQueue,
    domEventName,
    targetInst,
    nativeEvent,
    nativeEventTarget,
    eventSystemFlags,
    targetContainer,
  );
  // 执行dispatchQueue中具体事件执行路径下的事件
  processDispatchQueue(dispatchQueue, eventSystemFlags);
}
// 通过extractEvents合成的dispatchQueue的格式如下
[
  {
    // event是合成事件对象
    event, 
    // 具体的事件执行路径,currentTarget、listener等信息
    listeners: [
      {
        currentTarget: div.counter,
        instance: Fibernode {tag: 5, key: null, elementType: 'div', type: 'div', stateNode: div.counter, …},
        listener: e => {…}
      },
      {
        currentTarget: div.counter-parent,
        instance: FiberNode {tag: 5, key: null, elementType: 'div', type: 'div', stateNode: div.counter, …},
        listener: e => {…}
      }
    ] 
  }
]

React中模拟冒泡和捕获

原理:收集的事件放在dispatchQueue数组中,而冒泡和捕获的区别在于执行时机和顺序,那么我们只需要对数组按照不同顺序循环执行即可

function processDispatchQueueItemsInOrder(
  event: ReactSyntheticEvent,
  dispatchListeners: Array<DispatchListener>,
  inCapturePhase: boolean,
): void {
  let previousInstance;
​
  if (inCapturePhase) {
    // 事件捕获倒序循环
    for (let i = dispatchListeners.length - 1; i >= 0; i--) {
      const {instance, currentTarget, listener} = dispatchListeners[i];
      if (instance !== previousInstance && event.isPropagationStopped()) {
        return;
      }
      // 执行事件,传入event对象,和currentTarget
      executeDispatch(event, listener, currentTarget);
      previousInstance = instance;
    }
  } else {
    // 事件冒泡正序循环
    for (let i = 0; i < dispatchListeners.length; i++) {
      const {instance, currentTarget, listener} = dispatchListeners[i];
      // 如果事件对象阻止了冒泡,则return掉循环过程
      if (instance !== previousInstance && event.isPropagationStopped()) {
        return;
      }
      executeDispatch(event, listener, currentTarget);
      previousInstance = instance;
    }
  }
}

总结

以上就是最近学习React源码之--合成事件的知识整理啦!

首先会在fiber节点进入render阶段的complete阶段时,将事件监听绑定在root上。然后调用ensureListeningTo进行事件绑定,生成事件合成对象收集事件触发真正的事件

--结束END--

本文标题: React合成事件原理解析

本文链接: https://www.lsjlt.com/news/153643.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • React合成事件原理解析
    目录事件介绍什么是事件?举个栗子代码实现React合成事件基础知识什么是合成事件?在React中事件的写法和原生事件写法的区别?为什么会有合成事件?合成事件机制简述React合成事件...
    99+
    2022-11-13
  • react合成事件与原生事件的相关理解
    目录1. 原生事件 2. 合成事件 为什么react事件需要手动绑定this3. 原生与合成事件触发顺序4. 合成事件和原生事件混用 相关疑问:e.nativeEvent.stopP...
    99+
    2022-11-12
  • React合成事件的原理是什么
    这篇文章主要讲解了“React合成事件的原理是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“React合成事件的原理是什么”吧!事件介绍什么是事件?事件是在编程时系统内发生的动作或者发生...
    99+
    2023-07-02
  • react中合成事件与原生事件的示例分析
    小编给大家分享一下react中合成事件与原生事件的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1. 原生事件原生事件就是js的原生事件,如通过docum...
    99+
    2023-06-15
  • react源码合成事件深入解析
    目录引言导火线事件委托合成事件特点React 事件系统事件注册enqueuePutListener()listenTo()trapCapturedEvent 与 trapBubble...
    99+
    2023-01-06
    react源码合成事件 react 合成事件
  • React合成事件详解
    目录从点击输入框开始 扩展 点击输入框引起多个事件 为什么react中的input设置value后成为受控组件? 为什么合成事件属性有时无法访问? react如何模拟事件的阻止冒泡、...
    99+
    2022-11-12
  • React中的合成事件是什么原理
    目录事件介绍什么是事件React合成事件基础知识什么是合成事件为什么会有合成事件合成事件机制简述React合成事件实现原理事件注册React中模拟冒泡和捕获事件介绍 什么是事件 事件...
    99+
    2023-02-23
    React合成事件 React合成事件原理
  • React中合成事件的原理是什么
    本篇内容介绍了“React中合成事件的原理是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!事件介绍什么是事件事件是在编程时系统内发生的动...
    99+
    2023-07-05
  • React实现合成事件的源码分析
    目录事件绑定事件触发结尾今天尝试学习 React 事件的源码实现。 React 版本为 18.2.0 React 中的事件,是对原生事件的封装,叫做合成事件。抽象出一层合成事件,是为...
    99+
    2022-12-08
    React实现合成事件 React合成事件
  • react要用合成事件的原因是什么
    本文小编为大家详细介绍“react要用合成事件的原因是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“react要用合成事件的原因是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新...
    99+
    2022-10-19
  • 深入分析React源码中的合成事件
    目录热身准备明确几个概念事件系统角色划分事件注册registerSimpleEventsregisterEvents$2registerEvents$1registerEvents$...
    99+
    2022-11-13
    React源码合成事件 React 合成事件 React合成
  • react的合成事件是什么
    本篇内容介绍了“react的合成事件是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!React合成事件是React模拟原生DOM事件所有...
    99+
    2023-07-04
  • React如何实现合成事件
    本篇内容介绍了“React如何实现合成事件”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!事件绑定首先是 React 项目过程启动时,调用 l...
    99+
    2023-07-04
  • react的合成事件如何形容
    本教程操作环境:Windows7系统、react18版、Dell G3电脑。一、合成事件是什么React基于浏览器的事件机制自身实现了一套事件机制,包括事件注册、事件的合成、事件冒泡、事件派发等在React中这套事件机制被称之为合成事件合成...
    99+
    2023-05-14
    合成事件 React
  • React中的合成事件怎么实现
    这篇文章主要介绍了React中的合成事件怎么实现的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇React中的合成事件怎么实现文章都会有所收获,下面我们一起来看看吧。1 事件三个阶段 捕获、目标、处理 (具体百度...
    99+
    2023-07-05
  • react事件原理是怎样的
    react事件原理是怎样的,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。一 前言今天我们来一起探讨一下React事件原理,这篇文章,我尽量用通...
    99+
    2022-10-19
  • React事件机制源码解析
    目录原理简述 源码浅析 委托事件绑定 listenToAllSupportedEventslistenToNativeEvent addTrappedEventListener 不需...
    99+
    2022-11-12
  • React数据获取条件竞争原理解析
    目录引言Promise 简介Promise 和条件竞争条件竞争的起因解决条件竞争:强制重新挂载解决条件竞争:丢弃错误数据解决条件竞争:丢弃之前的数据解决条件竞争:取消之前的请求Asy...
    99+
    2023-01-29
    React 数据获取条件竞争 React 条件竞争
  • React中setState使用原理解析
    目录setState使用详解使用setState的原因setState的基本用法setState的异步更新setState获取异步结果setState一定是异步setState使用详...
    99+
    2022-11-13
    React setState使用 React setState
  • React事件处理的示例分析
    小编给大家分享一下React事件处理的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!React的事件处理和DOM的事件处...
    99+
    2022-10-19
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作