简体   繁体   English

单击React中可点击组件的外部

[英]Click outside of clickable components in React

I have a basic component that looks as follows. 我有一个基本组件,如下所示。

class List extends React.Component {
  constructor() {
    super(...arguments);
    this.state = {
      selected: null,
      entities: new Map([
        [0, { 'name': 'kot'} ],
        [1, { 'name': 'blini'} ]
      ])
    };
  }
  render() {
    return (<div>
      <ul>{this.renderItems()}</ul>
    </div>)
  }
  renderItems() {
    return Array.from(this.state.entities.entries()).map(s => {
      const [ id, entry ] = s;
      return <li
        key={id}
        onClick={() => this.setState(state => ({ selected: id }))}
        style={{
          color: id === this.state.selected ? 'red' : 'black'
        }}
      >{entry.name}</li>
    })
  }
}

This works in order to allow me to click on any element and select it. 这样可以让我点击任何元素并选择它。 A selected element will appear red. 所选元素将显示为红色。 codepen for easy editing . 用于轻松编辑的codepen

However, I want behavior that will unset any currently selected item if a click event was found that was not one of these <li> elements. 但是,如果发现的click事件不是这些<li>元素之一,我想要的行为将取消设置任何当前选定的项目。

How can this be done in React? 怎么能在React中完成?

In your List component, You can add List组件中,您可以添加

  componentDidMount() {
    window.addEventListener("click", (e) => {
      let withinListItems = ReactDOM.findDOMNode(this).contains(e.target);
      if ( ! withinListItems ) {
        this.setState({ selected: null });  
      }
    });
  }

And in your renderItems , change onClick to 在你的renderItems ,将onClick更改为

onClick={ (e) => {
    // e.stopPropagation();
    this.setState({ selected: id });
  }
}

You can checkout this codepen http://codepen.io/anon/pen/LRkzWd 你可以查看这个codepen http://codepen.io/anon/pen/LRkzWd

Edit: 编辑:

What @kubajz said is true, and hence i have updated the answer. @kubajz说的是真的,因此我更新了答案。

Random User's answer is correct, it may have one flaw - it relies on stopPropagation and there is possibility that some piece of code may no longer work as expected - imagine collecting user's behaviour on page and sending metrics somewhere - stopPropagation will prevent bubbling, thus click is not recorded. 随机用户的答案是正确的,它可能有一个缺陷 - 它依赖于stopPropagation并且有可能某些代码可能不再按预期工作 - 想象一下在页面上收集用户的行为并在某处发送指标 - stopPropagation将阻止冒泡,因此单击没有记录。 Alternative approach is to check what was clicked in event.target : http://codepen.io/jaroslav-kubicek/pen/ORXxkL 另一种方法是检查在event.target中点击的内容: http//codepen.io/jaroslav-kubicek/pen/ORXxkL

Also there is nice utility component for listening on document level: react-event-listener 还有一个很好的实用程序组件,用于监听文档级别: react-event-listener

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM