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