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>×</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">×</span></button>
<h4 className="modal-title">Modal title</h4>
</div>
<div className="modal-body">
<p>One fine body…</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">×</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">×</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">×</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;
주요 아이디어는 다음과 같습니다.
- 모달 요소(ReactElement 개체)를 복제합니다.
- div 요소를 만들어 문서 본문에 삽입합니다.
- 새로 삽입된 div 요소에서 복제된 모달 요소를 렌더링합니다.
- 렌더가 완료되면 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
'programing' 카테고리의 다른 글
retrofit API 콜을 디버깅하려면 어떻게 해야 하나요? (0) | 2023.03.15 |
---|---|
중첩된 JSON 개체 표시 해제 (0) | 2023.03.15 |
리액트 후크 : 하위 컴포넌트에서 상위 컴포넌트로 데이터를 전송합니다. (0) | 2023.03.15 |
반응 - 상태가 업데이트되지 않음 (0) | 2023.03.15 |
TypeScript를 사용한 함수 파라미터의 소품 파괴 (0) | 2023.03.15 |