我有:
export default class List extends Component {
...
render() {
return <div>
...
<DropdownMenu text="Only show" isOpen={this.state.activeDropdown === "Only_show"} onClick={() => this.setState({ activeDropdown: "Only_show"})} inMenu={this.state.mouseInDropdown} onMouseEnter={() => this.setState({ mouseInDropdown: true })} onMouseLeave={() => this.setState({ mouseInDropdown: false })}>
<li>New</li>
<li>Old</li>
</DropdownMenu>
...
</div>
DropdownMenu.js
import React, {Component} from 'react';
import onClickOutside from 'react-onclickoutside'
class DropdownMenu extends Component {
constructor(props) {
super(props)
this.state = {
menuOpen: this.props.isOpen,
highlight: false,
count: this.props.count | 0,
selection: null
}
this.showDropdown = this.showDropdown.bind(this);
this.selectItem = this.selectItem.bind(this);
this.menuIsOpen = false;
}
handleClickOutside = () => {
console.log('in menu:'+this.props.inMenu)
if(!this.props.inMenu) {
console.log('onClickOutside() method called')
}
}
showDropdown() {
if(this.props.children) {
this.setState({
menuOpen: !this.state.menuOpen
});
}
}
selectItem(e) {
console.log(e.target.textContent);
}
render() {
console.log(this.props.inMenu)
return <div className="dropdown__menu" onClick={this.props.onClick}>
{this.props.text} {this.state.count > 0 ? <b>{this.state.count}</b> : ''}
<div className="dropdown__content" style={this.props.isOpen ? {'display': 'block'} : {'display': 'none'}} onMouseEnter={this.props.onMouseEnter} onMouseLeave={this.props.onMouseLeave}>
{this.props.children}
</div>
</div>
}
}
export default onClickOutside(DropdownMenu)
我很难让this.props.isOpen
成为this.state.isOpen
,以便可以在handleClickOutside
中使用它。
另一个问题是好像多次被调用,我的控制台显示如下:
如何解决这些问题?
作为参考,这里是我正在使用的“外部点击”:Click Outside
答案 0 :(得分:0)
您的渲染功能正在查看this.props
,而不是this.state
。
在我看来,这应该可行(并且我简化了代码):
<div className="dropdown__content"
style={{'display': this.state.menuOpen ? 'block' : 'none'}}
onMouseEnter={this.props.onMouseEnter}
onMouseLeave={this.props.onMouseLeave} >
{this.props.children}
</div>
答案 1 :(得分:0)
正在发生的事情是您没有跟踪道具更改,即,当道具更改时,他们没有更新状态。您可以执行以下操作:
componentWillReceiveProps() {
this.setState({ menuOpen: this.props.isOpen })
}
但是,在测试中,我发现其他一些令我难以置信的事情使这变得比原本需要的困难。因此,这是工作代码的新答案(无需跟踪道具)。
我看不到(基于您所发布的内容)为什么List组件需要跟踪菜单状态和鼠标位置,因此我将两者都移到了DropdownMenu组件本身。您仍然可以将打开/关闭的默认值作为“ isOpen”道具传递。
List.js
import React, {Component} from 'react';
import DropdownMenu from './DropdownMenu'
export default class List extends Component {
render() {
return <div>
<DropdownMenu text="Only show" isOpen={false} >
<li>New</li>
<li>Old</li>
</DropdownMenu>
</div>
}
}
我将showDropdown
更改为toggleDropdown
,因为这是对其操作的更准确描述。鼠标位置移到了父div,我将selectItem
连接到了包含子项的div。
DropdownMenu.js
import React, {Component} from 'react';
import onClickOutside from 'react-onclickoutside'
class DropdownMenu extends Component {
constructor(props) {
super(props)
this.state = {
menuOpen: props.isOpen,
highlight: false,
count: props.count || 0,
selection: null,
mouseInDropdown: false,
}
this.toggleDropdown = this.toggleDropdown.bind(this);
this.selectItem = this.selectItem.bind(this);
}
handleClickOutside = () => {
if(!this.state.mouseInDropdown) {
// close it no matter what its state is
this.setState({menuOpen: false})
}
}
toggleDropdown() {
if(this.props.children) {
this.setState({
menuOpen: !this.state.menuOpen
});
}
}
selectItem(e) {
console.log(e.target.textContent);
}
render() {
//console.log("Render inMenu: " + this.state.mouseInDropdown)
return <div className="dropdown__menu"
onClick={this.toggleDropdown}
onMouseEnter={() => this.setState({ mouseInDropdown: true })}
onMouseLeave={() => this.setState({ mouseInDropdown: false })}>
{this.props.text} {this.state.count > 0 ? <b>{this.state.count}</b> : ''}
<div className="dropdown__content"
style={{'display': this.state.menuOpen ? 'block' : 'none'}}
onClick={this.selectItem}
>
{this.props.children}
</div>
</div>
}
}
export default onClickOutside(DropdownMenu)