Bootstrap 模式 React.js
Bootstrap modal in React.js
我需要通过单击 Bootstrap 导航栏和其他地方的按钮打开 Bootstrap 模式( 以显示组件实例的数据,即提供 "editing" 功能),但我不知道如何实现。这是我的代码:
编辑:代码已更新。
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>
);
}
});
感谢对代码的其他评论和改进。
只需将 href='#scheduleentry-modal'
添加到要使用
打开模态的元素
或使用jQuery:$('#scheduleentry-modal').modal('show');
你可以使用 React-Bootstrap (https://react-bootstrap.github.io/components/modal)。 link 处有一个模态示例。一旦加载了react-bootstrap,模态组件就可以作为react组件使用了:
var Modal = ReactBootstrap.Modal;
然后可以用作反应组件
<Modal/>
.
对于Bootstrap4,有react-strap(https://reactstrap.github.io)。 React-Bootstrap只支持Bootstrap 3.
我创建了这个函数:
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'));
}
然后用在我的按钮触发器上。
至 'hide' 模态框:
hideListItem: function () {
React.unmountComponentAtNode(document.querySelector('#modal-wrapper'));
},
我最近正在寻找一个很好的解决方案,而不是将 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 组件渲染函数中)。我保留了一些 'view' 状态,指示模态当前是否显示。
'componentDidMount' 和 'componentWillUnmount' 回调通过 Bootstrap javascript 函数隐藏或显示模式(一旦它被渲染到 React DOM) .
我认为这个解决方案很好地遵循了 React 的精神,但欢迎提出建议!
你可以试试这个模态:https://github.com/xue2han/react-dynamic-modal
它是无状态的,只有在 needed.So 时才能渲染,很容易 use.Just 像这样:
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'));
感谢@tgrrr 提供了一个简单的解决方案,尤其是当不需要第 3 方库时(例如 React-Bootstrap)。但是这个方案有一个问题:模态容器是嵌入在react组件内部的,当外部react组件(或其父元素)的position样式为fixed/relative/absolute时,会导致modal-under-background issue。我遇到了这个问题并提出了一个新的解决方案:
"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 also has an implementation of Bootstrap Modals in React。这个库针对 Bootstrap 版本 4,而 react-bootstrap 目标版本 3.X.
getDOMNode()
已弃用。而是使用 ref
访问 DOM 元素。这是工作模式组件 (Bootstrap 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 $ from 'jquery';
window.jQuery = $;
window.$ = $;
global.jQuery = $;
我只用了bootstrap cdn (css + js) 实现了"reactstrap" 之类的解决方案。我使用 props.children 将动态数据从父组件传递到子组件。您可以找到更多关于此 here 的信息。通过这种方式,您拥有三个独立的组件模态页眉、模态主体和模态页脚,它们彼此完全独立。
//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;
最快的解决方法是显式使用全局上下文中的 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 >
}
}
您可以使用来自 link 的 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>
</>
);
}
并且您可以将其转换为 class 组件
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>
);
}
}
我需要通过单击 Bootstrap 导航栏和其他地方的按钮打开 Bootstrap 模式( 以显示组件实例的数据,即提供 "editing" 功能),但我不知道如何实现。这是我的代码:
编辑:代码已更新。
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>
);
}
});
感谢对代码的其他评论和改进。
只需将 href='#scheduleentry-modal'
添加到要使用
或使用jQuery:$('#scheduleentry-modal').modal('show');
你可以使用 React-Bootstrap (https://react-bootstrap.github.io/components/modal)。 link 处有一个模态示例。一旦加载了react-bootstrap,模态组件就可以作为react组件使用了:
var Modal = ReactBootstrap.Modal;
然后可以用作反应组件
<Modal/>
.
对于Bootstrap4,有react-strap(https://reactstrap.github.io)。 React-Bootstrap只支持Bootstrap 3.
我创建了这个函数:
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'));
}
然后用在我的按钮触发器上。
至 'hide' 模态框:
hideListItem: function () {
React.unmountComponentAtNode(document.querySelector('#modal-wrapper'));
},
我最近正在寻找一个很好的解决方案,而不是将 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 组件渲染函数中)。我保留了一些 'view' 状态,指示模态当前是否显示。
'componentDidMount' 和 'componentWillUnmount' 回调通过 Bootstrap javascript 函数隐藏或显示模式(一旦它被渲染到 React DOM) .
我认为这个解决方案很好地遵循了 React 的精神,但欢迎提出建议!
你可以试试这个模态:https://github.com/xue2han/react-dynamic-modal 它是无状态的,只有在 needed.So 时才能渲染,很容易 use.Just 像这样:
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'));
感谢@tgrrr 提供了一个简单的解决方案,尤其是当不需要第 3 方库时(例如 React-Bootstrap)。但是这个方案有一个问题:模态容器是嵌入在react组件内部的,当外部react组件(或其父元素)的position样式为fixed/relative/absolute时,会导致modal-under-background issue。我遇到了这个问题并提出了一个新的解决方案:
"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 also has an implementation of Bootstrap Modals in React。这个库针对 Bootstrap 版本 4,而 react-bootstrap 目标版本 3.X.
getDOMNode()
已弃用。而是使用 ref
访问 DOM 元素。这是工作模式组件 (Bootstrap 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 $ from 'jquery';
window.jQuery = $;
window.$ = $;
global.jQuery = $;
我只用了bootstrap cdn (css + js) 实现了"reactstrap" 之类的解决方案。我使用 props.children 将动态数据从父组件传递到子组件。您可以找到更多关于此 here 的信息。通过这种方式,您拥有三个独立的组件模态页眉、模态主体和模态页脚,它们彼此完全独立。
//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;
最快的解决方法是显式使用全局上下文中的 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 >
}
}
您可以使用来自 link 的 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>
</>
);
}
并且您可以将其转换为 class 组件
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>
);
}
}