Sivadass N
Sivadass N

Reputation: 927

React JS onClick Open Current Dropdown Menu

I am having n number of dropdown menus in React JS. When I am clicking nth menu item, I want to open the corresponding dropdown menu. But what I am getting now is, on clicking a menu item, all the dropdowns are getting opened. How this can be achieved?

class Menubar extends React.Component {
  constructor() {
    super();
    this.state = {
      clicked: false
    };
    this.handleClick = this.handleClick.bind(this);
    this.handleOutsideClick = this.handleOutsideClick.bind(this);
  }

  componentWillMount() {
        document.addEventListener('click', this.handleOutsideClick, false);
    }

    componentWillUnmount(){
        document.removeEventListener('click', this.handleOutsideClick, false);
    }
  handleClick() {
    this.setState({clicked: !this.state.clicked});
  }
  handleOutsideClick(event){
        if (!this.refs.megaMenu.contains(event.target)) {
      this.setState({
                clicked: false
            });
        } 
  }
  render() {
    return (
      <div className="container">
        <div className="menu-bar">

          <div className="menu-bar-item" ref="megaMenu">
            <a className="menu-bar-link" href="#" onClick={this.handleClick}>First Menu</a>
            <div className={"mega-menu"+" "+this.state.clicked}>
              <div className="mega-menu-content">
                <p>First Menu</p>
              </div>
            </div>
          </div>

          <div className="menu-bar-item" ref="megaMenu">
            <a className="menu-bar-link" href="#" onClick={this.handleClick}>Second Menu</a>
            <div className={"mega-menu"+" "+this.state.clicked}>
              <div className="mega-menu-content">
                <p>Second Menu</p>
              </div>
            </div>
          </div>

          <div className="menu-bar-item" ref="megaMenu">
            <a className="menu-bar-link" href="#" onClick={this.handleClick}>Third Menu</a>
            <div className={"mega-menu"+" "+this.state.clicked}>
              <div className="mega-menu-content">
                <p>Third Menu</p>
              </div>
            </div>
          </div>

          <div className="menu-bar-item" ref="megaMenu">
            <a className="menu-bar-link" href="#" onClick={this.handleClick}>Fourth Menu</a>
            <div className={"mega-menu"+" "+this.state.clicked}>
              <div className="mega-menu-content">
                <p>Fourth Menu</p>
              </div>
            </div>
          </div>

        </div>
      </div>
    );
  }
}

ReactDOM.render(
  <Menubar />,
  document.getElementById('example')
);

Codepen Demo Here

Upvotes: 1

Views: 15388

Answers (2)

crystalthinker
crystalthinker

Reputation: 1182

You have used a single state i.e clicked for all of the menu items, this will triger for all the menus when there is a setState called.

you should have seperate state for checking the clicks for each menu items. or make an array say clicked[] . and then change the value of a particular clicked state. eg: ...

<div className="menu-bar-item" ref="megaMenu">
            <a className="menu-bar-link" href="#" onClick={this.handleClick.bind(this,1)}>Second Menu</a>
            <div className={"mega-menu"+" "+this.state.clicked[1]}>
              <div className="mega-menu-content">
                <p>Second Menu</p>
              </div>
            </div>
          </div>

.... and define the handleClick as

 handleClick(index,e) {
  let clicked=this.state.clicked;
    clicked[index]=!clicked[index]
    this.setState({clicked:clicked});
  }

here is the codepen link : http://codepen.io/anon/pen/oLRbmq

Upvotes: 2

Igorsvee
Igorsvee

Reputation: 4201

All dropdowns are getting selected because of this <div className={"mega-menu"+" "+this.state.clicked}>, they all use the same variable from the state - clicked, thus if you click on one all of them change state.If you only want a specific dropdown to get selected, you need to declare a new variable in the state for every corresponding dropdown element and also change the logic handleClick accordingly.

Upvotes: 1

Related Questions