programing

React.js의 부트스트랩모달

elseif 2023. 3. 15. 19:24

React.js의 부트스트랩모달

부트스트랩 네비게이션 바 및 기타 장소(컴포넌트 인스턴스의 데이터 표시, 즉 "편집" 기능 제공)에서 버튼을 클릭하여 부트스트랩 모달(Modal)을 열어야 하는데, 이 작업을 수행하는 방법을 모르겠습니다.코드는 다음과 같습니다.

EDIT: 코드가 갱신되었습니다.

ApplicationContainer = React.createClass({
    render: function() {
        return (
            <div className="container-fluid">
            <NavBar />
                <div className="row">
                    <div className="col-md-2">
                        <ScheduleEntryList />
                    </div>
                    <div className="col-md-10">
                    </div>
                </div>
                <ScheduleEntryModal />
            </div>
        );
    }
});

NavBar = React.createClass({
    render: function() {
        return (
            <nav className="navbar navbar-default navbar-fixed-top">
                <div className="container-fluid">
                    <div className="navbar-header">
                        <a className="navbar-brand" href="#">
                            <span className="glyphicon glyphicon-eye-open"></span>
                        </a>
                    </div>
                    <form className="navbar-form navbar-left">
                        <button className="btn btn-primary" type="button" data-toggle="modal" data-target="#scheduleentry-modal">
                            <span className="glyphicon glyphicon-plus">
                            </span>
                        </button>
                    </form>
                    <ul className="nav navbar-nav navbar-right">
                        <li><a href="#"><span className="glyphicon glyphicon-user"></span> Username</a></li>
                    </ul>
                </div>
            </nav>
        );
    }
});

ScheduleEntryList = React.createClass({
    getInitialState: function() {
        return {data: []}
    },

    loadData: function() {
        $.ajax({
            url: "/api/tasks",
            dataType: "json",

            success: function(data) {
                this.setState({data: data});
            }.bind(this),

            error: function(xhr, status, error) {
                console.error("/api/tasks", status, error.toString());
            }.bind(this)
        });
    },

    componentWillMount: function() {
        this.loadData();
        setInterval(this.loadData, 20000);
    },

    render: function() {
        items = this.state.data.map(function(item) {
            return <ScheduleEntryListItem item={item}></ScheduleEntryListItem>;
        });

        return (
            <div className="list-group">
                <a className="list-group-item active">
                    <h5 className="list-group-item-heading">Upcoming</h5>
                </a>
                {items}
            </div>
        );
    }
});

ScheduleEntryListItem = React.createClass({
    openModal: function() {
        $("#scheduleentry-modal").modal("show");
    },

    render: function() {
        deadline = moment(this.props.item.deadline).format("MMM Do YYYY, h:mm A");

        return (
            <a className="list-group-item" href="#" onClick={this.openModal}>
                <h5 className="list-group-item-heading">
                    {this.props.item.title}
                </h5>
                <small className="list-group-item-text">
                    {deadline}
                </small>
            </a>
        );
    }
});

Modal = React.createClass({
    componentDidMount: function() {
        $(this.getDOMNode())
            .modal({backdrop: "static", keyboard: true, show: false});
    },

    componentWillUnmount: function() {
        $(this.getDOMNode())
            .off("hidden", this.handleHidden);
    },

    open: function() {
        $(this.getDOMNode()).modal("show");
    },

    close: function() {
        $(this.getDOMNode()).modal("hide");
    },

    render: function() {
        return (
            <div id="scheduleentry-modal" className="modal fade" tabIndex="-1">
                <div className="modal-dialog">
                    <div className="modal-content">
                        <div className="modal-header">
                            <button type="button" className="close" data-dismiss="modal">
                                <span>&times;</span>
                            </button>
                            <h4 className="modal-title">{this.props.title}</h4>
                        </div>
                        <div className="modal-body">
                            {this.props.children}
                        </div>
                        <div className="modal-footer">
                            <button type="button" className="btn btn-danger pull-left" data-dismiss="modal">Delete</button>
                            <button type="button" className="btn btn-primary">Save</button>
                        </div>
                    </div>
                </div>
            </div>

        )
    }
});

ScheduleEntryModal = React.createClass({
    render: function() {
        var modal = null;
        modal = (
            <Modal title="Add Schedule Entry">
                    <form className="form-horizontal">
                        <div className="form-group">
                            <label htmlFor="title" className="col-sm-2 control-label">Title</label>
                            <div className="col-sm-10">
                                <input id="title" className="form-control" type="text" placeholder="Title" ref="title" name="title"/>
                            </div>
                        </div>
                        <div className="form-group">
                            <label htmlFor="deadline" className="col-sm-2 control-label">Deadline</label>
                            <div className="col-sm-10">
                                <input id="deadline" className="form-control" type="datetime-local" ref="deadline" name="deadline"/>
                            </div>
                        </div>
                        <div className="form-group">
                            <label htmlFor="completed" className="col-sm-2 control-label">Completed</label>
                            <div className="col-sm-10">
                                <input id="completed" className="form-control" type="checkbox" placeholder="completed" ref="completed" name="completed"/>
                            </div>
                        </div>
                        <div className="form-group">
                            <label htmlFor="description" className="col-sm-2 control-label">Description</label>
                            <div className="col-sm-10">
                                <textarea id="description" className="form-control" placeholder="Description" ref="description" name="description"/>
                            </div>
                        </div>
                    </form>
            </Modal>
        );

        return (
            <div className="scheduleentry-modal">
                {modal}
            </div>
        );
    }
});

코드에 대한 기타 코멘트 및 개선사항에 감사드립니다.

저는 최근에 프로젝트에 React-Bootstrap을 추가하지 않고 이에 대한 좋은 해결책을 찾고 있었습니다(Bootstrap 4가 곧 출시됩니다).

이것이 저의 솔루션입니다.https://jsfiddle.net/16j1se1q/1/

let Modal = React.createClass({
    componentDidMount(){
        $(this.getDOMNode()).modal('show');
        $(this.getDOMNode()).on('hidden.bs.modal', this.props.handleHideModal);
    },
    render(){
        return (
          <div className="modal fade">
            <div className="modal-dialog">
              <div className="modal-content">
                <div className="modal-header">
                  <button type="button" className="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                  <h4 className="modal-title">Modal title</h4>
                </div>
                <div className="modal-body">
                  <p>One fine body&hellip;</p>
                </div>
                <div className="modal-footer">
                  <button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
                  <button type="button" className="btn btn-primary">Save changes</button>
                </div>
              </div>
            </div>
          </div>
        )
    },
    propTypes:{
        handleHideModal: React.PropTypes.func.isRequired
    }
});



let App = React.createClass({
    getInitialState(){
        return {view: {showModal: false}}
    },
    handleHideModal(){
        this.setState({view: {showModal: false}})
    },
    handleShowModal(){
        this.setState({view: {showModal: true}})
    },
    render(){
    return(
        <div className="row">
            <button className="btn btn-default btn-block" onClick={this.handleShowModal}>Open Modal</button>
            {this.state.view.showModal ? <Modal handleHideModal={this.handleHideModal}/> : null}
        </div>
    );
  }
});

React.render(
   <App />,
    document.getElementById('container')
);

주요 아이디어는 Modal 구성 요소를 표시할 때만 React DOM으로 렌더링하는 것입니다(App 구성 요소 렌더 기능).현재 모달 표시 여부를 나타내는 몇 가지 '보기' 상태를 유지합니다.

componentDidMount' 및 componentWillUnmount' 콜백은 Bootstrap javascript 함수를 통해 모달(일단 React DOM에 렌더링된 후)을 숨기거나 표시합니다.

이 솔루션은 리액트 정신을 잘 따르고 있다고 생각합니다만, 제안은 환영입니다.

React-Bootstrap(https://react-bootstrap.github.io/components/modal)을 사용할 수 있습니다.그 링크에는 모달의 예가 있습니다.리액트 부트스트랩을 로드하면 모달컴포넌트를 리액트컴포넌트로 사용할 수 있습니다.

var Modal = ReactBootstrap.Modal;

다음으로 반응 성분으로 사용할 수 있다<Modal/>.

부트스트랩4에는 리액트스트랩(https://reactstrap.github.io)이 있습니다.React-Bootstrap은 Bootstrap 3만 지원합니다.

getDOMNode()는 권장되지 않습니다.대신 사용ref액세스 할 수 있습니다.여기 동작하는 Modal 컴포넌트(부트스트랩 4)가 있습니다.부모 컴포넌트에 Modal 컴포넌트를 표시할지 여부를 결정합니다.

예: 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>
        );
    }
}

편집:

기능하기 위해 필요한 Import는 다음과 같습니다.

import $ from 'jquery';
window.jQuery = $;
window.$ = $;
global.jQuery = $;

부트스트랩 cdn(css + js)을 사용하여 "리액트스트랩"과 같은 솔루션을 구현했습니다.부모 컴포넌트에서 자녀 컴포넌트로 동적 데이터를 전달하기 위해 소품, 자녀 컴포넌트를 사용했습니다.자세한 내용은 이쪽에서 확인하실 수 있습니다.이 방법에서는 3개의 개별 컴포넌트 모달 헤더, 모달 본문 및 모달 바닥글이 있으며 이들은 서로 완전히 독립적입니다.


//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;

이 함수를 만들었습니다.

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'));
}

그리고 내 버튼 트리거에 그걸 사용했지

모달 '숨기기' 방법

hideListItem: function () {
    React.unmountComponentAtNode(document.querySelector('#modal-wrapper'));
},

링크의 react-bootstrap 모델을 사용할 수 있으며 기본적으로는 함수 기반입니다.

function Example() {
  const [show, setShow] = useState(false);
  const handleClose = () => setShow(false);
  const handleShow = () => setShow(true);
  return (
    <>
      <Button variant="primary" onClick={handleShow}>
        Launch demo modal
      </Button>

      <Modal show={show} onHide={handleClose} animation={false}>
        <Modal.Header closeButton>
          <Modal.Title>Modal heading</Modal.Title>
        </Modal.Header>
        <Modal.Body>Woohoo, you're reading this text in a modal!</Modal.Body>
        <Modal.Footer>
          <Button variant="secondary" onClick={handleClose}>
            Close
          </Button>
          <Button variant="primary" onClick={handleClose}>
            Save Changes
          </Button>
        </Modal.Footer>
      </Modal>
    </>
  );
}

클래스 컴포넌트로 변환할 수 있습니다.

import React, { Component } from "react";
import { Button, Modal } from "react-bootstrap";


export default class exampleextends Component {
  constructor(props) {
    super(props);
    this.state = {
      show: false,
      close: false,
    };
  } 
  render() {
    return (
      <div>
        <Button
          variant="none"
          onClick={() => this.setState({ show: true })}
        >
          Choose Profile
        </Button>
        <Modal
          show={this.state.show}
          animation={true}
          size="md" className="" shadow-lg border">
          <Modal.Header className="bg-danger text-white text-center py-1">
            <Modal.Title className="text-center">
              <h5>Delete</h5>
            </Modal.Title>
          </Modal.Header>
          <Modal.Body className="py-0 border">
            body   
          </Modal.Body>
<Modal.Footer className="py-1 d-flex justify-content-center">
              <div>
                <Button
                  variant="outline-dark" onClick={() => this.setState({ show: false })}>Cancel</Button>
              </div>
              <div>
                <Button variant="outline-danger" className="mx-2 px-3">Delete</Button>
              </div>
            </Modal.Footer>
        </Modal>
      </div>
    );
  }
}

이 모달은 사용할 수 있습니다.https://github.com/xue2han/react-dynamic-modal 이 모달은 스테이트리스이며 필요한 경우에만 렌더링할 수 있습니다.그래서 그것은 매우 사용하기 쉽다.바로 다음과 같습니다.

    class MyModal extends Component{
       render(){
          const { text } = this.props;
          return (
             <Modal
                onRequestClose={this.props.onRequestClose}
                openTimeoutMS={150}
                closeTimeoutMS={150}
                style={customStyle}>
                <h1>What you input : {text}</h1>
                <button onClick={ModalManager.close}>Close Modal</button>
             </Modal>
          );
       }
    }

    class App extends Component{
        openModal(){
           const text = this.refs.input.value;
           ModalManager.open(<MyModal text={text} onRequestClose={() => true}/>);
        }
        render(){
           return (
              <div>
                <div><input type="text" placeholder="input something" ref="input" /></div>
                <div><button type="button" onClick={this.openModal.bind(this)}>Open Modal </button> </div>
              </div>
           );
        }
    }

    ReactDOM.render(<App />,document.getElementById('main'));

특히 서드파티 라이브러리가 필요 없는 경우(React-Bootstrap 등)에는 @tgrr이 심플한 솔루션을 제공합니다.단, 이 솔루션에는 문제가 있습니다.모달 용기는 반응 컴포넌트 내부에 내장되어 있기 때문에 외부 반응 컴포넌트(또는 그 부모 요소)가 고정/상대/절대 위치 스타일을 가질 경우 모달 언더 백그라운드 문제가 발생합니다.저는 이 문제를 해결하고 새로운 해결책을 찾았습니다.

"use strict";

var React = require('react');
var ReactDOM = require('react-dom');

var SampleModal = React.createClass({
  render: function() {
    return (
      <div className="modal fade" tabindex="-1" role="dialog">
        <div className="modal-dialog">
          <div className="modal-content">
            <div className="modal-header">
              <button type="button" className="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
              <h4 className="modal-title">Title</h4>
            </div>
            <div className="modal-body">
              <p>Modal content</p>
            </div>
            <div className="modal-footer">
              <button type="button" className="btn btn-default" data-dismiss="modal">Cancel</button>
              <button type="button" className="btn btn-primary">OK</button>
            </div>
          </div>
        </div>
      </div>
    );
  }
});

var sampleModalId = 'sample-modal-container';
var SampleApp = React.createClass({
  handleShowSampleModal: function() {
    var modal = React.cloneElement(<SampleModal></SampleModal>);
    var modalContainer = document.createElement('div');
    modalContainer.id = sampleModalId;
    document.body.appendChild(modalContainer);
    ReactDOM.render(modal, modalContainer, function() {
      var modalObj = $('#'+sampleModalId+'>.modal');
      modalObj.modal('show');
      modalObj.on('hidden.bs.modal', this.handleHideSampleModal);
    }.bind(this));
  },
  handleHideSampleModal: function() {
    $('#'+sampleModalId).remove();
  },
  render: function(){    
    return (
      <div>
        <a href="javascript:;" onClick={this.handleShowSampleModal}>show modal</a>
      </div>
    )
  }
});

module.exports = SampleApp;

주요 아이디어는 다음과 같습니다.

  1. 모달 요소(ReactElement 개체)를 복제합니다.
  2. div 요소를 만들어 문서 본문에 삽입합니다.
  3. 새로 삽입된 div 요소에서 복제된 모달 요소를 렌더링합니다.
  4. 렌더가 완료되면 modal을 표시합니다.또한 모달 숨김 시 새로 삽입된 div 요소가 제거되도록 이벤트청취자를 연결합니다.

Reactstrap은 또한 React에 Bootstrap Modals를 구현합니다.이 라이브러리는 부트스트랩 버전4를 대상으로 하고 react-bootstrap은 버전 3.X를 대상으로 합니다.

부트스트랩5와 리액트 훅으로 동작하는 코드는 다음과 같습니다.

  const ref = React.useRef<HTMLDivElement>(null);
  React.useEffect(() => {
    if (ref.current) {
      ref.myModal = new bootstrap.Modal(ref.current, { backdrop: true });
    }
  }, [ref]);

모드를 표시하려면 이 코드를 내 컴포넌트 내에서 사용합니다.

 <button
    className="btn btn-primary"
    onClick={() => {
      if (ref.myModal) {
        ref.myModal.show();
      }
    }}
  >
    open modal
  </button>
  <div
    className="modal fade"
    tabIndex={-1}
    aria-labelledby="uploadYoutubeModalLabel"
    aria-hidden="true"
    ref={ref}
  >
    <div className="modal-dialog">bla</div>
  </div>

이 결속하다myModel하면, 「」를 할 수 .ref.myModal.show() the를 ref.myModal.hide()

가장 빠른 수정은 글로벌콘텍스트에서 jQuery $를 명시적으로 사용하는 것입니다(이는 스크립트태그에서 참조했기 때문에 $.modal()로 확장되었습니다).

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

그래서 이렇게 반응해서

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 >
    }
}

더하면 돼요.href='#scheduleentry-modal'[을하여 모달

jQuery: "jQuery" 를 사용합니다.$('#scheduleentry-modal').modal('show');

언급URL : https://stackoverflow.com/questions/28241912/bootstrap-modal-in-react-js