2017-06-18 40 views
0

我写了一个简单的下拉菜单,因为我想要不同的样式并对行为有更多的控制,但现在我被困在使用户点击其他地方时关闭下拉菜单身体或其他元素。我如何用纯粹的反应来实现这一目标?单击正文以改变状态,以响应关闭下拉菜单

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

回答

0

组件时负载添加事件侦听到身体。

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

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

这将有问题,如果我有多个下拉菜单。 –

+0

是的。为了有多个下拉菜单,您需要保存哪个下拉菜单处于打开状态,并且只有在点击正文时才关闭该下拉菜单。 –

-1

我改名为你的状态更好的理解,也改变了你对渲染到UL的div,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> 

     ) 
} 
}); 
+0

只有'li'应该放在'ul'里面,不过其他的东西可以放在'li'里面 –

+0

没有看到有另一个ul。要解决这个问题。 –