如何使用React.js门户关闭和卸载Bootstrap模式

时间:2019-02-17 13:19:50

标签: reactjs bootstrap-4 modal-dialog

我正在创建一个模式来激活表格中一行的onClick。该模式将出现并显示表行包含的所有数据。我已经能够看到模态,但是安装后我无法将其关闭。

我以为状态没有更新,因为setState需要一个回调函数立即触发它,但这对我不起作用。

// Modal.js
import React, { Component } from 'react'
import ReactDOM from 'react-dom'

const modalRoot = document.getElementById('modal-root');

class Modal extends React.Component {
    el = document.createElement('div');

    componentDidMount() {
        modalRoot.appendChild(this.el);
    }

    componentWillUnmount() {
        modalRoot.removeChild(this.el);
    }

    render() {
        // Use a portal to render the children into the element
        return ReactDOM.createPortal(
            <div className="modal fade show" id="exampleModal" tabIndex="-1" role="dialog" aria-labelledby="exampleModalLabel" data-keyboard="false" data-backdrop="static" style={{display: 'block'}} aria-modal="true">
                <div className="modal-dialog" role="document">
                    <div className="modal-content">
                        <div className="modal-header">
                            <h5 className="modal-title" id="exampleModalLabel">Modal title</h5>
                                <button onClick={ this.handleHide } type="button" className="close" aria-label="Close">
                                    <span aria-hidden="true">&times;</span>
                                </button>
                            </div>
                        <div className="modal-body">
                            { this.props.children }
                        </div>
                        <div className="modal-footer">
                            <button onClick={ this.props.onClose } type="button" className="btn btn-secondary">Close</button>
                            <button type="button" className="btn btn-primary">Save changes</button>
                        </div>
                    </div>
                </div>
            </div>,
        this.el);
    }
}

export default Modal

// FlightLogSummary.js
import React, { Component } from 'react'
import Modal from '../layout/Modal'

class FlightLogSummary extends React.Component {
    state = {showModal: false}

    handleShow = () => {
        this.setState({showModal: true});
    }

    handleHide = () => {
        this.setState({showModal: false});
    }

    render() {
        const { flightLog } = this.props

        const modal = this.state.showModal ? (
            <Modal>
                Modalidy
            </Modal>
        ) : null;

        return (
            <tr onClick={ this.handleShow }>
                <th scope="row">{ flightLog.flightDate }</th>
                <td>{ flightLog.flightRoute }</td>
                <td>{ flightLog.flightAircraft }</td>
                <td className="text-right">{ flightLog.flightTotal }</td>
                { modal }
            </tr>
        )
    }
}

export default FlightLogSummary;

模式应由行上的onClick触发。模态应该出现。单击模式的关闭按钮后,它应该会消失。

2 个答案:

答案 0 :(得分:0)

您可以将React库中的modal用于引导。您可以使用react-bootstrapreactstrap中的模式。这些库与react更兼容。

除此之外,handleHide函数位于FlightLogSummary中,而您正尝试在Modal组件中对其进行访问。您可以关注:

<Modal close={this. handleHide}>
   Modalidy
</Modal>
// in Modal component
<button onClick={this.props.close} type="button" className="close" aria-label="Close">
  <span aria-hidden="true">&times;</span>
</button>

您还可以在console.log()函数中添加handleHide来检查它是否被调用。

答案 1 :(得分:0)

您不需要createPortal,因为子级已经作为道具传递了。只需将onClose函数传递给Modal组件即可。

我在这里使用了一个按钮来切换模式组件,但是您也可以将onClick句柄传递给tr元素。

此外,利用setState函数参数根据先前的状态值更新状态。

class Modal extends React.Component {
  render() {
    return (
      <div className="modal fade show" id="exampleModal" tabIndex="-1" role="dialog" aria-labelledby="exampleModalLabel" data-keyboard="false" data-backdrop="static" style={{display: 'block'}} aria-modal="true">
        <div className="modal-dialog" role="document">
          <div className="modal-content">
            <div className="modal-header">
              <h5 className="modal-title" id="exampleModalLabel">Modal title</h5>
              <button onClick={this.props.onClose} type="button" className="close" aria-label="Close">
                <span aria-hidden="true">&times;</span>
              </button>
            </div>
            <div className="modal-body">
              {this.props.children}
            </div>
            <div className="modal-footer">
              <button onClick={this.props.onClose} type="button" className="btn btn-secondary">Close</button>
              <button type="button" className="btn btn-primary">Save changes</button>
            </div>
          </div>
        </div>
      </div>
    )
  }
}

class FlightLogSummary extends React.Component {
    state = { showModal: false }

    toggleModal = () => {
      this.setState(prevState => ({ showModal: !prevState.showModal }))
    }

    render() {          
      return (
        <div>
          {/* <tr onClick={this.toggleModal}> ... </tr> */}
          <button onClick={this.toggleModal}>Toggle Modal</button>
          {this.state.showModal && <Modal onClose={this.toggleModal}>Modality</Modal>}
        </div>
      )
    }
}