React事件机制

作者: 月半君o | 来源:发表于2019-05-19 19:29 被阅读8次

react事件机制分为两个部分:1、事件注册 2、事件分发

  • 事件注册部分,所有的事件都会注册到document上,拥有统一的回调函数dispatchEvent来执行事件分发
  • 事件分发部分,首先生成合成事件,注意同一种事件类型只能生成一个合成事件Event,如onclick这个类型的事件,dom上所有带有通过jsx绑定的onClick的回调函数都会按顺序(冒泡或者捕获)会放到Event._dispatchListeners 这个数组里,后面依次执行它。

事件注册

  • ReactDOMComponent在进行组件加载(mountComponent)、更新(updateComponent)的时候,需要对props进行处理(_updateDOMProperties):
ReactDOMComponent.Mixin = {
  _updateDOMProperties: function (lastProps, nextProps, transaction) {
    ...
    for (propKey in nextProps) {
      // 判断是否为事件属性
      if (registrationNameModules.hasOwnProperty(propKey)) {
        enqueuePutListener(this, propKey, nextProp, transaction);
      }
    }
  }
}
function enqueuePutListener(inst, registrationName, listener, transaction) {
  ...
  var doc = isDocumentFragment ? containerInfo._node : containerInfo._ownerDocument;
  // 在document上注册事件,同一个事件类型只会被注册一次
  listenTo(registrationName, doc);
  // mountReady之后将回调函数存在ListernBank中
  transaction.getReactMountReady().enqueue(putListener, {
    inst: inst,
    registrationName: registrationName,
    listener: listener
  });
  function putListener() {
    var listenerToPut = this;
    EventPluginHub.putListener(listenerToPut.inst, listenerToPut.registrationName, listenerToPut.listener);
  }
}
  • enqueuePutListener进行两件事情: 在document上注册相关的事件;对事件进行存储
    document的事件注册入口位于ReactBrowserEventEmitter:
// ReactBrowserEventEmitter.js
listenTo: function (registrationName, contentDocumentHandle) {
  ...
  if (...) {
    ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(...);
  } else if (...) {
    ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(...);
  }
  ...
}

// ReactEventListener.js
var ReactEventListener = {
  ...
  trapBubbledEvent: function (topLevelType, handlerBaseName, element) {
    ...
    var handler = ReactEventListener.dispatchEvent.bind(null, topLevelType);
    return EventListener.listen(element, handlerBaseName, handler);
  },
  trapCapturedEvent: function (topLevelType, handlerBaseName, element) {
    var handler = ReactEventListener.dispatchEvent.bind(null, topLevelType);
    return EventListener.capture(element, handlerBaseName, handler);
  }
  dispatchEvent: function (topLevelType, nativeEvent) {
    ...
    ReactUpdates.batchedUpdates(handleTopLevelImpl, bookKeeping);
    ...
  }
}
function handleTopLevelImpl(bookKeeping) {
  ...
  ReactEventListener._handleTopLevel(bookKeeping.topLevelType, targetInst, bookKeeping.nativeEvent, getEventTarget(bookKeeping.nativeEvent));
  ...
}
  • 事件的注册、触发,具体是在ReactEventListener中实现的
  • 事件的注册有两个方法: 支持冒泡(trapBubbledEvent)、捕获(trapCapturedEvent)
  • document不管注册的是什么事件,具有统一的回调函数- handleTopLevelImpl
  • document的回调函数中不包含任何的事物处理,只起到事件分发的作用

事件分发

事件注册完之后,就可以依据事件委托进行事件的执行。由事件注册可以知道,几乎所有的事件均委托到document上,而document上事件的回调函数只有一个: ReactEventListener.dispatchEvent,然后进行相关的分发:

var ReactEventListener = {
  dispatchEvent: function (topLevelType, nativeEvent) {
    ...
    ReactUpdates.batchedUpdates(handleTopLevelImpl, bookKeeping);
    ...
  }
}
function handleTopLevelImpl(bookKeeping) {
  var nativeEventTarget = getEventTarget(bookKeeping.nativeEvent);
  var targetInst = ReactDOMComponentTree.getClosestInstanceFromNode(nativeEventTarget);

  // 初始化时用ReactEventEmitterMixin注入进来的
  ReactEventListener._handleTopLevel(..., nativeEventTarget, targetInst);
}
// ReactEventEmitterMixin.js
var ReactEventEmitterMixin = {
  handleTopLevel: function (...) {
    var events = EventPluginHub.extractEvents(...);
    runEventQueueInBatch(events);
  }
}
function runEventQueueInBatch(events) {
  EventPluginHub.enqueueEvents(events);
  EventPluginHub.processEventQueue(false);
}
  • handleTopLevelImpl: 根据原生的事件对象,找到事件触发的dom元素以及该dom对应的compoennt对象
  • ReactEventEmitterMixin: 一方面生成合成的事件对象,另一方面批量执行定义的回调函数
  • runEventQueueInBatch: 进行批量更新
参考文章: https://segmentfault.com/a/1190000013364457

相关文章

  • --

    react事件机制 react基于浏览器原生事件机制,封装了一套自己的事件机制,包括事件注册、事件合成、冒泡和捕获...

  • 【React进阶系列】史上最全React事件机制详解

    框架总览 ? DOM事件流的三个阶段 ? 关于React事件的疑问? React事件绑定机制? React事件和原...

  • React 事件处理机制

    React在处理事件和HTML中JS处理事件不同,本文介绍React中的事件处理机制。React中不同通过返回fa...

  • React学习之漫谈React

    事件系统 合成事件的绑定方式 Test 合成事件的实现机制:事件委派和自动绑定。 React合成事件系统的委托机制...

  • React事件机制

    上一篇讲述了React事件的使用,这一篇主要讲述React的事件机制,主要包含事件注册、触发以及回调函数的存储,最...

  • React 事件机制

    简述 1 .当我们在组件上设置事件处理器时,React并不会在改DOM元素上直接绑定事件处理器,而是在react内...

  • react 事件机制

    手动绑定this 1 .注册事件被调用的时候,回调函数是直接调用的,并没有指定调用的组件,所以不进行手动绑定,此时...

  • react事件机制

    (1)react合成事件 react合成事件执行过程: 合成事件与原生事件的区别 1. 写法不同,合适事件是驼峰写...

  • React事件机制

    react事件机制分为两个部分:1、事件注册 2、事件分发 事件注册部分,所有的事件都会注册到document上,...

  • react 事件机制

    一、合成事件 react 基于 vitrual dom 实现了 syntheticEvent (合成事件),rea...

网友评论

    本文标题:React事件机制

    本文链接:https://www.haomeiwen.com/subject/nzwnaqtx.html