Toggle dropdown menu in reactjs

I have the following code for a simple drop-down menu on my navigator: https://jsfiddle.net/jL3yyk98/10/

index.html

<div id="menu-button"></div>

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

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'));

In my current code, I understand that both the toggleMenu method and the onClose method are called when the user presses the menu button to close the menu (since they also click on the body efficiently); and that the onClose method is called first, which means that the state is set to false, but then the toggleMenu method is called and returns to true. Why is this and how can I fix it so that clicking on the menu button switches the menu and clicking on the body hides the menu?

, ? , , , .

, div , ; , (, ), .

+4
2

, . , :

  • This.state.open false
  • Render this.state.open false
  • This.state.open true
  • Render this.state.open true

e.stopPropagation() React. :

handleBodyClick: function(e)
{
    if (e.target.nodeName !== 'A') {
       this.setState({isOpen: false});
    }
},

( ) , , div, ( ).

div : https://jsfiddle.net/jL3yyk98/

+2
handleClose: function() {
  this.setState({isOpen: false});
},

handleGlobalClick: function(event) {
  var _con = this.refs.mC.getDOMNode() // <component ref="mC">
  if (!(_con == event.target) && !_con.contains(event.target)) {
    this.handleClose();
  }
},

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

componentWillUnmount: function() {
  document.body.removeEventListener('click', this.handleGlobalClick);
},

, jQuery node.contains()

0

All Articles