首页 > 解决方案 > 检测组件外部的点击反应方式不是 dom 访问

问题描述

我正在使用 React 实现裁剪功能。当用户右键单击时,会出现一个上下文菜单。在上下文菜单中,用户可以选择裁剪项目。当用户选择裁剪时,裁剪被激活。现在,我想在用户在该分区之外单击时关闭裁剪状态。我如何在没有 DOM 操作的情况下做出反应?还是我必须使用 DOM 操作,例如add EventListener & removeListener?在这里使用 DOM 访问有什么缺点?请让我彻底了解这一点,因为这将在我将开发的许多功能中实现。例如,我正在谈论的上下文菜单或下拉菜单。

这是参考示例 - Sandbox。现在,当用户点击ReactCrop组件外部时,我想通过反应方式关闭裁剪。

我不想继续document.addEventListener or removeListener

标签: javascriptreactjsdomreact-state-management

解决方案


如果您真的,真的不想将 dom 事件附加到您的组件,您可以在组件后面添加一个“dismisser”组件Crop并在那里处理重置。

const Dismisser = ({ onClick }) => <div onClick={onClick} style={{
  position: 'fixed',
  top: 0, left: 0, right: 0, bottom: 0,
  zIndex: 100,
}} />

在您的组件中:

{src && (
  <React.Fragment>
  <div style={{position: 'relative', zIndex: 200}}>
    <ReactCrop
      src={src}
      crop={crop}
      ...
    />
  </div>
  <Dismisser onClick={this.resetCrop} />
  </React.Fragment>
)}

代码沙盒

我会说这有点“React-y”,因为重置作物的责任被委托给了另一个组件。但是,当您的 Crop 组件落后于其他 Dom 元素时,它会给您带来麻烦,z-index 明智。您可以通过使用门户来克服它,但它会开始变得复杂。

我认为在这里附加 DOM 事件是一个有效的解决方案(只要你记得删除它们)。它更简单,而且不像您使用 React 流之外的数据直接操作 dom 节点,这在大多数情况下是真正的坏情况。


推荐阅读