简体   繁体   English

如何关闭模态 window 在 React + Redux 应用程序中单击外部?

[英]How to close a modal window clicking outside in React + Redux app?

Making an application (react + redux).制作应用程序(react + redux)。 It contains a few photos.它包含几张照片。 When you click a photo you get a modal window with bigger photo and comments.当你点击一张照片时,你会得到一个带有更大照片和评论的模态 window。

Code for ModalContainer (contains modal window itself): ModalContainer 的代码(包含 modal window 本身):

class ModalContainer extends Component {
  state = {
    name: '',
    comment: '',
  }

  componentDidMount() {
    const { isOpen, closeModal } = this.props
    if (isOpen) {
      document.body.style.overflow = 'hidden'
    }
    document.addEventListener('click', closeModal)
  }

  componentWillUnmount() {
    const { closeModal } = this.props
    document.body.style.overflow = 'auto'
    document.removeEventListener('click', closeModal)
  }

  inputChange = (e) => {
    this.setState({
      [e.target.name]: e.target.value,
    })
  }

  putComment = (e) => {
    e.preventDefault()
    const { comment, name } = this.state
    const { photo } = this.props
    axios
      .post(
        `https://boiling-refuge-66454.herokuapp.com/images/${photo.id}/comments`,
        { name: name, comment: comment, date: Date.parse(String(new Date())) }
      )
      .then((res) => {
        console.log(res)
      })
    this.setState({
      name: '',
      comment: '',
    })
  }

  render() {
    const { name, comment } = this.state
    const { closeModal, photo } = this.props
    const comments = photo.comments
    return (
      <>
        <Modal
          onClick={closeModal}
          src={photo.url}
          comments={comments}
          name={name}
          comment={comment}
          onChange={this.inputChange}
          onSubmit={this.putComment}
        />
      </>
    )
  }
}

export default connect(
  ({ modal }) => ({
    photo: modal.photo,
    isOpen: modal.isOpen,
  }),
  { closeModal }
)(ModalContainer)

As you can see I have this code document.addEventListener('click', closeModal) inside componentDidMount() lifecycle method.如您所见,我在componentDidMount()生命周期方法中有此代码document.addEventListener('click', closeModal) Brackets contains action creator closeModal , which closes my modal.括号包含动作创建者closeModal ,它关闭了我的模态。 In that case it doesn't work correctly because it launches action creator even if I click inside my modal.在这种情况下,它无法正常工作,因为即使我在我的模态中单击它也会启动动作创建器。 So I can't add comment inside.所以我不能在里面添加评论。

In this case, what is the proper way to close a modal window by clicking outside a window?在这种情况下,通过单击 window 外部关闭模态 window 的正确方法是什么?

if Modal is a class component you can add ref to it (if it's a function component use fowardRef )如果Modal是 class 组件,则可以向其添加ref (如果它是 function 组件,请使用fowardRef

<Modal ref={modalNode => (this.modalNode = modalNode)}

and adapt your eventListener并调整您的 eventListener

handleClick = e => !this.modalNode.contains(e.target) && closeModal();

 componentDidMount() {
    const { isOpen, closeModal } = this.props
    if (isOpen) {
      document.body.style.overflow = 'hidden'
    }
    document.addEventListener('click', this.handleClick)
  }

A common practice is to wrap Modal in an ModalOverlay ,一种常见的做法是将Modal包装在ModalOverlay中,

style ModalOverlay to be full screen.样式ModalOverlay为全屏。

function onOverlayClick(e) {
  closeModal()
  e.stopPropagation()
}

function onModalClick(e) {
  // need to stop propagation to ModalOverlay onClick event
  e.stopPropagation()
}

return (
      <div className="full-screen" onClick={onOverlayClick}>
        <Modal
          onClick={onModalClick}
          src={photo.url}
          comments={comments}
          name={name}
          comment={comment}
          onChange={this.inputChange}
          onSubmit={this.putComment}
        />
      <div/>
    )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM