�
�
­2019-01-06 18:26:44
React
­, 2019-01-06 18:26:44

How to hide Menu when clicked outside its box (Javascript) (React js)?

Here, there is such a simple menu component

class Menu extends Component {

  state = { show: false }

  toggleMenu = () => {
    this.setState({ show: !this.state.show })
  }

  render() {
    const { show } = this.state
    return(
      <div>
        <button onClick={this.toggleMenu}>MENU</button>
        {
          show 
            ? <ul>
                <li>qwe</li>
                <li>asd</li>
                <li>zxc</li>
              </ul>
            : undefined
        }
      </div>
    )
  }
}

I know how to close the menu when clicking on one of its items.
But how to close the menu when you click on the pink zone? (That is, anywhere, but not on the menu)
5c321cf2071bc220802138.png
There is an idea to make it through a div that will overlap all other objects against the background of the menu. Make it transparent, and have an onClick that hides the menu and this invisible div. Somehow through z-index.
But I want to read your answers, your ways.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Anton Spirin, 2019-01-06
@640

Something like this:

class Menu extends Component {
  state = { isActive: false };
  
  wrapper = React.createRef();
  
  componentWillUnmount() {
    this.removeOutsideClickListener();
  }
  
  addOutsideClickListener() {
    document.addEventListener('click', this.handleDocumentClick);
  }

  removeOutsideClickListener() {
    document.removeEventListener('click', this.handleDocumentClick);
  }
  
  onShow() {
    this.addOutsideClickListener();
  }
  
  onHide() {
    this.removeOutsideClickListender();
  }
  
  onClickOutside() {
    this.setState({ isActive: false });
  }  

  handleDocumentClick = e => {
    if (this.wrapper.current && !this.wrapper.current.contains(e.target)) {
      this.onClickOutside();
    }
  };
  
  toggleMenu = () => {
    this.setState(
      prevState => ({ isActive: !prevState.isActive }),
      () => {
        this.state.isActive ? this.onShow() : this.onHide();
      },
    );
  };

  render() {
    const { isActive } = this.state;

    return(
      <div ref={this.wrapper}>
        <button onClick={this.toggleMenu}>MENU</button>
        {isActive && ( 
          <ul>
            <li>qwe</li>
            <li>asd</li>
            <li>zxc</li>
          </ul>
        )}
      </div>
    )
  }
}

G
grinat, 2019-01-06
@grinat

You hang an onclick handler on window and if an event comes there you close the menu, in toggleMenu = () => { you do toggleMenu = (e) => { e.stopPropagation(); e.nativeEvent.stopImmediatePropagation();
In general, the point is that all events they pop up to the very top right up to window, and so that in the menu itself it does not pop up up to window you stop the flashing

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question