首页 > 解决方案 > 反应:关闭一个模态点击外部

问题描述

我有一个模态反应组件,带有一个打开模态的按钮。模式也有一个关闭按钮。这是代码和模态的样子:

class Modal extends React.Component {
    static defaultProps = {
        title: "Modal Title",
        float: false,
        color: "pink",
        children: <div>Add children here!</div>
    }

    constructor(props) {
        super(props)
        this.state = {
            show: false
        }
    }

    openModal() {
        this.setState(
            { show: true }
        )
    }

    closeModal() {
        this.setState(
            { show: false }
        );
    }

    render() {
        return (
            <div>
                <button className={"modal-button" + " " + this.props.color} onClick={() => this.openModal()}>{this.props.title}</button>
                {this.state.show && <div className={"modal fade-in" + " " + (this.props.float ? "modal-float" : null)}>
                    <div className="modal-head">
                        <span>{this.props.title}</span>
                        <button id='button' onClick={() => this.closeModal()}>x</button>
                    </div>
                    <div className="modal-body">
                        {this.props.children}
                    </div>
                </div>}
            </div>
        )
    }
}

它有一个打开模式的按钮。 模态也有一个关闭按钮。

我想关闭在外面点击的模式。在另一个问题中,我看到了这样的代码

handleClick = event => {
    event.preventDefault();

    this.setState({ showModal: true }, () => {
      document.addEventListener("click", this.closeMenu);
    });
  };

closeMenu = () => {
    this.setState({ menuOpen: false }, () => {
      document.removeEventListener('click', this.closeMenu);
    });
  }

但是当我在模态框内单击时,它也会关闭模态框。

标签: javascriptreactjs

解决方案


您需要添加一个条件,当模态打开并且单击源自模态内部时不会关闭模态。要检测点击发生的位置,您可能会使用 refs。

https://reactjs.org/docs/refs-and-the-dom.html

例如,我在 closeMenu 函数中添加了这个条件:

this.modalRef = React.createRef();

handleClick = event => {
    event.preventDefault();

    this.setState({ showModal: true }, () => {
      document.addEventListener("click", this.closeMenu);
    });
  };

closeMenu = () => {
  if(this.modalRef.current && this.modalRef.current.contains(event.target)) {
    return; 
}
    this.setState({ menuOpen: false }, () => {
      document.removeEventListener('click', this.closeMenu);
    });
  }


render() {
    return (
      <div ref={this.modalRef}>
       // modal component 
      </div>
    );
  }
}

这会检测 1. 模态是否打开 ( this.modalRef.current) 和 2. 如果单击源自模态内部 ( this.modalRef.current.contains(event.target)),在这种情况下它会返回并且不会关闭模态。

这解释了该方法,尽管它使用钩子而不是类组件,但概念是相同的:https ://javascript.plainenglish.io/detect-a-click-outside-of-a-react-component-with-a-reusable -hook-and-useref-a0c282171c3f


推荐阅读