Reactjs - 在页面上的任何地方单击外部时切换下拉菜单,而不仅仅是单击图标

IT技术 javascript reactjs
2021-04-27 11:41:30

我有一个 React js 应用程序(请不要使用 JQuery)下拉菜单,当单击 ▼ 字符时会触发该下拉菜单。使用下面的代码,只有再次单击相同的 ▼ 时,下拉菜单才会消失。我想让它在用户点击页面上的任何其他地方时消失。如何更改下面的代码以使下拉菜单在用户单击页面上的任何其他位置时消失,而不仅仅是单击相同的图标 ▼ ?

切换器图标:

      <span className="show_more" onClick={this.toggleOptions}>
        <MaterialIcon icon="keyboard_arrow_down" />
      </span>

切换代码:(被许多组件使用,所以修复只能在这里吗?)

import React, { Component } from 'react'
...
import MaterialIcon from '../icons/material-icon'
import HeaderLogo from './logo'

export default class Header extends Component {
  state = {
    showOptions: false,
  }

  toggleOptions = () => this.setState({ showOptions: !this.state.showOptions })

  render() {
    let { showOptions } = this.state

    return (
      <div className="header">
        <div className="row-container container">
          <div className="col-l">
            <HeaderLogo />
          </div>
          <div className="col-m">
            <Search />
          </div>
          <div className="col-r">
            <div className="header_right">
              <HeaderTopLinks />
              <span className="show_more" onClick={this.toggleOptions}>
                <MaterialIcon icon="keyboard_arrow_down" />
              </span>
            </div>

            {showOptions ? (
              <HeaderOptions toggleOptions={this.toggleOptions} />
            ) : null}
          </div>
        </div>
      </div>
    )
  }
}
1个回答

答案可以在这里找到

但总而言之,您必须监听文档上的点击,并编写一个函数来遍历树并告诉您点击是发生在组件内部还是外部

以下是该链接中要添加到组件中的重要部分:

  handleClickOutside(event) {
    if (this.wrapperRef && !this.wrapperRef.contains(event.target)) {
      alert('You clicked outside of me!');
      this.setState({ showOptions: false });
    }
  }

  componentDidMount() {
    document.addEventListener('mousedown', this.handleClickOutside);
  }

  componentWillUnmount() {
    document.removeEventListener('mousedown', this.handleClickOutside);
  }

  render() {
    let { showOptions } = this.state;

    return <div className="header" ref={(node) => this.setWrapperRef = node}>...all the rest of the component goes here...</div>;
  }

为了记录,有很多方法可以实现这一点,这只是一种方法。