问题描述
我在导航栏上有一个用于简单下拉菜单的以下代码:
I have the following code for a simple dropdown menu on my navbar: https://jsfiddle.net/jL3yyk98/10/
index.html
index.html
<div id="menu-button"></div>
NavMenu.js
NavMenu.js
var NavMenu = React.createClass({
getDefaultProps: function()
{
return {
isOpen: false
};
},
render: function()
{
if (this.props.isOpen)
{
return (
<div className="dropdown">
<ul>
<li><a href="#">News</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Guidelines</a></li>
<li><a href="#">Exchange</a></li>
<li><a href="#">Forum</a></li>
</ul>
</div>
);
}
return null;
}
});
NavMenuButton.js
NavMenuButton.js
var NavMenuButton = React.createClass({
getInitialState: function()
{
return {
isOpen: false
};
},
toggleMenu: function(e)
{
e.stopPropagation();
this.setState({isOpen: !this.state.isOpen});
},
onClose: function()
{
this.setState({isOpen: false});
},
componentDidMount: function ()
{
document.body.addEventListener('click', this.onClose);
},
componentWillUnmount: function ()
{
document.body.removeEventListener('click', this.onClose);
},
render: function()
{
return (
<div>
<a onClick={this.toggleMenu} href="#">Menu</a>
<NavMenu isOpen={this.state.isOpen} />
</div>
);
}
});
React.render(<NavMenuButton />, document.getElementById('menu-button'));
根据我当前的代码,我了解到,当用户单击时,toggleMenu方法和onClose方法都会被调用菜单按钮以关闭菜单(因为它们也有效地单击了主体);并且先调用onClose方法,这意味着将状态设置为false,然后再调用toggleMenu方法并将其重新设置为true。为什么会这样,如何解决该问题,以便单击菜单按钮可以切换菜单,而单击正文会隐藏菜单?
I understand with my current code that both the toggleMenu method and onClose method are called when the user clicks the menu button to close the menu (since they are also effectively clicking the body); and that the onClose method is called first, meaning that the state is set to false, but then the toggleMenu method is called and it's set back to true. Why is this, and how can I fix it so that clicking the menu button toggles the menu and clicking the body hides the menu?
如果这种方法似乎是错误的,我应该使用哪种方法?我现在还很陌生,所以我仍然在学习哪里以及为什么去做。
If this approach seems wrong what approach should I be using? I'm fairly new to react so I'm still learning what goes where and why.
此外,我不能使用全身div作为解决方案,它需要是一个典型的下拉列表;因此,如果用户想与页面的另一部分进行交互(也许单击链接),那么他们可以这样做。
Also, I cannot use a full body div as the solution to this, it needs to be a typical dropdown; so if users want to interact with another part of the page (maybe clicking a link), then they can do that.
推荐答案
您的问题是,单击链接也将调用主体单击侦听器。这意味着您的状态将来自以下位置:
Your issue is that clicking on the link will also call the body click listener. It means that your state will go from:
- 单击链接
- 单击名为 body的侦听器
- This.state.open设置为false
- 使用this.state.open false调用的渲染
- 单击名为
- This.state.open设置为true的链接上的侦听器
- 使用this.state.open true进行渲染的渲染
- Click on link
- Click listener on body called
- This.state.open set to false
- Render called with this.state.open false
- Click listener on the link called
- This.state.open set to true
- Render called with this.state.open true
e.stopPropagation()在React中不起作用。一种解决方法是:
e.stopPropagation() doesn't work in React. One workaround would be to:
handleBodyClick: function(e)
{
if (e.target.nodeName !== 'A') {
this.setState({isOpen: false});
}
},
另一种方法(也是更好的方法)是让点击侦听器不在主体上,而在div上,并使其尽可能大(基本上与主体大小相同)。
Another way (and better way) would be to have the click listener not on body, but on a div, and make it as big as possible (to be as the same size a body basically).
这是绑定单击div而不是单击正文的示例:
这篇关于在reactjs中切换下拉菜单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!