检测到组件外部的点击反应不访问DOM

时间:2019-01-18 05:48:38

标签: javascript reactjs dom react-state-management

我正在用React实现裁剪功能。当用户右键单击时,将显示一个上下文菜单。在上下文菜单中,用户可以选择作物项目。当用户选择裁剪时,裁剪将被激活。现在,我想在用户单击该分区以外的区域时关闭裁剪状态。没有DOM操作,我该怎么做?还是应该使用诸如add EventListener & removeListener之类的DOM操作?在这里使用DOM访问有什么弊端?请让我彻底知道这一点,因为这将在我将要开发的许多功能中实现。例如,我正在谈论的上下文菜单或下拉菜单。

以下是参考示例-Sandbox。现在,当用户在ReactCrop组件之外单击时,我想通过反应方式关闭作物。

我不想继续使用document.addEventListener or removeListener

1 个答案:

答案 0 :(得分:1)

如果您确实不想将dom事件附加到组件,则可以在Crop组件后面添加一个“ dismisser”组件,并在那里进行重置。

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>
)}

Codesandbox

我想说的是更多的“ React-y”,因为重置作物的责任委托给了另一个组件。但是,如果您的Crop组件位于其他Dom元素(z-index明智)之后,则会给您带来麻烦。您可以使用门户网站克服它,但是它将变得越来越复杂。

我认为在这里附加DOM事件是一个有效的解决方案(只要您记得将其删除即可)。它更简单,而且还不代表您使用React流之外的数据直接操纵dom节点,而在大多数情况下,这是最糟糕的情况。