点击正文以更改状态以响应关闭下拉列表

时间:2017-06-18 23:00:29

标签: javascript reactjs

我写了一个简单的下拉菜单,因为我想要不同的风格,并且对行为有更多的控制权,但是现在当用户点击身体的其他地方或其他元素时,我仍然停下来关闭下拉菜单。如何用纯粹的反应实现这一目标?

var Hello = React.createClass({
  getInitialState() {
     return {
        openDropdown: false
     }
  },

  toggleDropdown: function() {
     this.setState({
         openDropdown: !this.state.openDropdown
     })
  },

  render: function() {
    return (
        <ul>
        <p onClick={this.toggleDropdown.bind(this)}>Select</p>
        <div className={this.state.openDropdown ? 'show' : 'hide'}>
        <li>item 1</li>
        <li>item 2</li>
        <li>item 3</li>
        </div>
      </ul>

    )
  }
});

https://jsfiddle.net/1z5zpqeo

2 个答案:

答案 0 :(得分:0)

在加载组件时向主体添加事件侦听器。

componentDidMount: function() {
  document.body.addEventListener('click', this.closeDropdwn);
},

closeDropdwn: function() {
  this.setState({
    openDropdown: false,
  })
},

答案 1 :(得分:-1)

我为了更好的理解而重命名了你的状态,同时,将你的渲染上的div改为ul,li元素永远不应该在ul之外的任何其他元素内。

此外,更多的分裂,以便在需要时更容易调试。

var Hello = React.createClass({
    getInitialState() {
        return {
            isOpenDropdown: false //rename for better understanding
        }
    },

    toggleDropdown: function(e) {
        if(e && ReactDOM.findDOMNode(this.refs.dropdown).contains(e.target)) {
            return; //Ignore click if it was inside the dropdown
    }
    this.state.isOpenDropdown ? this.closeDropdown() : this.openDropdown()
},

openDropdown: function() {
    document.addEventListener("click", this.closeDropdown);
    this.setState({
        isOpenDropdown: true
    });
},

closeDropdown: function() {
    document.removeEventListener("click", this.closeDropdown);
    this.setState({
        isOpenDropdown: false
    });
}

componentWillUnmount: function() {
    if(this.state.isOpenDropdown){
        document.removeEventListener("click", this.closeDropdown);
    }
}

render: function() {
    //Changed "div" to "ul" -- LI should never be inside any element other than UL.
    return (
        <div>
        <p onClick={this.toggleDropdown.bind(this)}>Select</p>
        <ul className={this.state.isOpenDropdown ? 'show' : 'hide'}> 
        <li>item 1</li>
        <li>item 2</li>
        <li>item 3</li>
        </ul>
        </div>

        )
}
});