Как закрыть и размонтировать мод загрузки с помощью порталов React.js - PullRequest
0 голосов
/ 17 февраля 2019

Я создаю модал, чтобы активировать 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;

Модальный режим должен быть вызван щелчком по строке.Модал должен появиться.При нажатии кнопки закрытия модального окна оно должно исчезнуть.

Ответы [ 2 ]

0 голосов
/ 17 февраля 2019

Вам не нужен createPortal для этого, потому что потомки уже переданы как реквизиты.Просто передайте функцию onClose модальному компоненту.

Я использовал здесь кнопку для переключения модального компонента, но вы также можете передать дескриптор 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>
      )
    }
}

0 голосов
/ 17 февраля 2019

Вы можете использовать modal из библиотек реагирования для начальной загрузки.Вы можете использовать модал из реагирующий бутстрап или реагирующий ремень .Эти библиотеки более совместимы с реагируют.

Кроме этого, функция 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 функцию, чтобы проверить, вызывается она или нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...