Bootstrap modal in React.js

前端 未结 12 1359
别跟我提以往
别跟我提以往 2020-12-02 07:19

I need to open a Bootstrap Modal from clicking on a button in a Bootstrap navbar and other places (to show data for a component instance, ie. providing \"editing\" f

相关标签:
12条回答
  • 2020-12-02 08:09

    I've only used bootstrap cdn (css + js) to achieve "reactstrap" like solution. I've used props.children to pass dynamic data from parent to child components. You can find more about this here. In this way you have three separate components modal header, modal body and modal footer and they are totally independent from each other.


    //Modal component
    import React, { Component } from 'react';
    
    export const ModalHeader = props => {
      return <div className="modal-header">{props.children}</div>;
    };
    
    export const ModalBody = props => {
      return <div className="modal-body">{props.children}</div>;
    };
    
    export const ModalFooter = props => {
      return <div className="modal-footer">{props.children}</div>;
    };
    
    class Modal extends Component {
      constructor(props) {
        super(props);
        this.state = {
          modalShow: '',
          display: 'none'
        };
        this.openModal = this.openModal.bind(this);
        this.closeModal = this.closeModal.bind(this);
      }
    
      openModal() {
        this.setState({
          modalShow: 'show',
          display: 'block'
        });
      }
    
      closeModal() {
        this.setState({
          modalShow: '',
          display: 'none'
        });
      }
    
      componentDidMount() {
        this.props.isOpen ? this.openModal() : this.closeModal();
      }
    
      componentDidUpdate(prevProps) {
        if (prevProps.isOpen !== this.props.isOpen) {
          this.props.isOpen ? this.openModal() : this.closeModal();
        }
      }
    
      render() {
        return (
          <div
            className={'modal fade ' + this.state.modalShow}
            tabIndex="-1"
            role="dialog"
            aria-hidden="true"
            style={{ display: this.state.display }}
          >
            <div className="modal-dialog" role="document">
              <div className="modal-content">{this.props.children}</div>
            </div>
          </div>
        );
      }
    }
    
    export default Modal;
    
    //App component
    import React, { Component } from 'react';
    import Modal, { ModalHeader, ModalBody, ModalFooter } from './components/Modal';
    
    import './App.css';
    
    class App extends Component {
      constructor(props) {
        super(props);
        this.state = {
          modal: false
        };
        this.toggle = this.toggle.bind(this);
      }
    
      toggle() {
        this.setState({ modal: !this.state.modal });
      }
    
      render() {
        return (
          <div className="App">
            <h1>Bootstrap Components</h1>
    
            <button
              type="button"
              className="btn btn-secondary"
              onClick={this.toggle}
            >
              Modal
            </button>
    
            <Modal isOpen={this.state.modal}>
              <ModalHeader>
                <h3>This is modal header</h3>
                <button
                  type="button"
                  className="close"
                  aria-label="Close"
                  onClick={this.toggle}
                >
                  <span aria-hidden="true">&times;</span>
                </button>
              </ModalHeader>
              <ModalBody>
                <p>This is modal body</p>
              </ModalBody>
              <ModalFooter>
                <button
                  type="button"
                  className="btn btn-secondary"
                  onClick={this.toggle}
                >
                  Close
                </button>
                <button
                  type="button"
                  className="btn btn-primary"
                  onClick={this.toggle}
                >
                  Save changes
                </button>
              </ModalFooter>
            </Modal>
          </div>
        );
      }
    }
    
    export default App;
    
    
    0 讨论(0)
  • 2020-12-02 08:10

    getDOMNode() is deprecated. Instead use ref to access DOM element. Here is working Modal component (Bootstrap 4). Decide whether to show or not to show Modal component in parent component.

    Example: https://jsfiddle.net/sqfhkdcy/

    class Modal extends Component {
        constructor(props) {
            super(props);
        }
        componentDidMount() {
            $(this.modal).modal('show');
            $(this.modal).on('hidden.bs.modal', handleModalCloseClick);
        }
        render() {
            return (
                <div>
                    <div className="modal fade" ref={modal=> this.modal = modal} id="exampleModal" tabIndex="-1" role="dialog" aria- labelledby="exampleModalLabel" aria-hidden="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 type="button" className="close" data- dismiss="modal" aria-label="Close">
                                        <span aria-hidden="true">&times;</span>
                                    </button>
                                </div>
                                <div className="modal-body">
                                    ...
                                </div>
                                <div className="modal-footer">
                                    <button type="button" className="btn btn-secondary" data- dismiss="modal">Close</button>
                                    <button type="button" className="btn btn-primary">Save changes</button>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            );
        }
    }
    

    Edit:

    Here are the necessary imports to make it work:

    import $ from 'jquery';
    window.jQuery = $;
    window.$ = $;
    global.jQuery = $;
    
    0 讨论(0)
  • 2020-12-02 08:10

    I Created this function:

    onAddListItem: function () {
        var Modal = ReactBootstrap.Modal;
        React.render((
            <Modal title='Modal title' onRequestHide={this.hideListItem}>
                <ul class="list-group">
                    <li class="list-group-item">Cras justo odio</li>
                    <li class="list-group-item">Dapibus ac facilisis in</li>
                    <li class="list-group-item">Morbi leo risus</li>
                    <li class="list-group-item">Porta ac consectetur ac</li>
                    <li class="list-group-item">Vestibulum at eros</li>
                </ul>
            </Modal>
        ), document.querySelector('#modal-wrapper'));
    }
    

    And then used it on my Button trigger.

    To 'hide' the Modal:

    hideListItem: function () {
        React.unmountComponentAtNode(document.querySelector('#modal-wrapper'));
    },
    
    0 讨论(0)
  • 2020-12-02 08:16

    Solution using React functional components.

    import React, { useState, useRef, useEffect } from 'react'
    
    const Modal = ({ title, show, onButtonClick }) => {
    
        const dialog = useRef({})
    
        useEffect(() => { $(dialog.current).modal(show ? 'show' : 'hide') }, [show])
        useEffect(() => { $(dialog.current).on('hide.bs.modal', () =>
            onButtonClick('close')) }, [])
    
        return (
            <div className="modal fade" ref={dialog}
                id="modalDialog" tabIndex="-1" role="dialog"
                aria-labelledby="modalDialogLabel" aria-hidden="true"
            >
                <div className="modal-dialog" role="document">
                    <div className="modal-content">
                        <div className="modal-header">
                            <h5 className="modal-title" id="modalDialogLabel">{title}</h5>
                            <button type="button" className="close" aria-label="Close"
                                onClick={() => onButtonClick('close')}
                            >
                                <span aria-hidden="true">&times;</span>
                            </button>
                        </div>
                        <div className="modal-body">
                            ...
                        </div>
                        <div className="modal-footer">
                            <button type="button" className="btn btn-secondary"
                                onClick={() => onButtonClick('close')}>Close</button>
                            <button type="button" className="btn btn-primary"
                                onClick={() => onButtonClick('save')}>Save</button>
                        </div>
                    </div>
                </div>
            </div>
        )
    }
    
    const App = () => {
    
        const [ showDialog, setShowDialog ] = useState(false)
    
        return (
            <div className="container">
                <Modal
                    title="Modal Title"
                    show={showDialog}
                    onButtonClick={button => {
                        if(button == 'close') setShowDialog(false)
                        if(button == 'save') console.log('save button clicked')
                    }}
                />
                <button className="btn btn-primary" onClick={() => {
                    setShowDialog(true)
                }}>Show Dialog</button>
            </div>
        )
    }
    
    0 讨论(0)
  • 2020-12-02 08:16

    Just add href='#scheduleentry-modal' to the element you want to open the modal with

    Or using jQuery: $('#scheduleentry-modal').modal('show');

    0 讨论(0)
  • 2020-12-02 08:18

    The quickest fix would be to explicitly use the jQuery $ from the global context (which has been extended with your $.modal() because you referenced that in your script tag when you did ):

      window.$('#scheduleentry-modal').modal('show') // to show 
      window.$('#scheduleentry-modal').modal('hide') // to hide
    

    so this is how you can about it on react

    import React, { Component } from 'react';
    
    export default Modal extends Component {
        componentDidMount() {
            window.$('#Modal').modal('show');
        }
    
        handleClose() {
            window.$('#Modal').modal('hide');
        }
    
        render() {
            <
            div className = 'modal fade'
            id = 'ModalCenter'
            tabIndex = '-1'
            role = 'dialog'
            aria - labelledby = 'ModalCenterTitle'
            data - backdrop = 'static'
            aria - hidden = 'true' >
                <
                div className = 'modal-dialog modal-dialog-centered'
            role = 'document' >
                <
                div className = 'modal-content' >
                // ...your modal body
                <
                button
            type = 'button'
            className = 'btn btn-secondary'
            onClick = {
                    this.handleClose
                } >
                Close <
                /button> < /
            div > <
                /div> < /
            div >
        }
    }
    
    
    0 讨论(0)
提交回复
热议问题