克隆React合成事件实例

16

使用原生JS可以像这样克隆事件实例:

const cloneEvent = event => new event.constructor(event.type, event);

可以用来将一个DOM元素的事件转发到另一个DOM元素。例如,

const buttonA = document.querySelector('#a');
const buttonB = document.querySelector('#a');

const clickHandler = (type, forwardTo) => event => {
  console.log(type, 'was clicked');
  if (forwardTo) forwardTo.dispatchEvent(cloneEvent(event));
};

buttonA.addEventListener('click', clickHandler('A', buttonB));
buttonA.addEventListener('click', clickHandler('B'));

当您单击A时,您还将看到两个按钮的2个日志记录。
我希望使用React的SyntheticEvent实现相同的效果,但我遇到了问题,可能是因为SyntheticEvent的实例化方式与本机事件不同。这里有一个演示该问题的实时演示:https://jsfiddle.net/2Lhsfceu/2/(请参阅dev控制台日志)
我的当前解决方案是克隆本机事件(SyntheticEvent.nativeEvent),如下所示(更新并工作的实时演示:https://jsfiddle.net/2Lhsfceu/1/
const cloneEvent = event => {
  const nativeEvent = event.nativeEvent || event;
  new nativeEvent.constructor(nativeEvent.type, nativeEvent);
}

我想知道是否有更好的方法,或者这已经是我们能做到的最好的了?

我的担忧是,仅克隆本机事件,代码库正在处理两种不同类型的事件:来自React的合成事件和转发而来的本机事件。


不确定您想要实现什么,但是假设您想在单击另一个元素后调度单击事件,则可以手动触发另一个元素的引用上的单击。更干净的方法是只调用所有所需的事件处理程序,但这取决于情况。 - Yegor Belov
1个回答

1

一旦在DOM上调度本地事件就像手动滚动一样,那么它应该没问题。

我的担忧是仅克隆本地事件,代码库正在处理两种不同类型的事件:源事件(来自React)分派的SyntheticEvent和转发的本地事件。

React所做的是监听根节点上的所有本地事件(这里是<div id="#root"/>,它们通过冒泡到达),然后每次接收到一个事件时,它都会创建一个等效的SyntheticEvent,并将其传递给React代码。

因此,如果您手动触发本地事件,React将像往常一样创建它们的SyntheticEvent等效项,这应该没问题。

在非常罕见的情况下,在Javascript中手动分派事件将产生与真实用户触发事件不同的效果。请参见this example


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接