react中使用Modal模态框

在前端开发中,弹出模态框是经常会碰到的,我们在项目中用到的有两种方式,一种是自己实现,一种是用react-bootstrap中的Modal组件
首先看看我们要实现的功能

image.png

点击弹出示例对话框 的时候,弹出模态框。
我们在react中会把这个弹出的模态框封装成一个组件,这样就可以实现重复应用。
主页代码如下:

import React, {Component } from 'react';
import PropTypes from 'prop-types';
import { Link,Button,ButtonToolbar} from 'react-bootstrap';
import DeleteBusiness from 'component/manage/business/DeleteBusiness';
import Util from 'util';
const propTypes = {
};
class Modal extends Component {
    static propTypes={
    }
    constructor(props) {
        super(props);
        this.state = {
            show:false,
        };
        Util.bindFunction([
            'remove',
            'getModalButtons',
            'removeShow'

        ], this);
    }
    remove(){
        this.setState({
            show:true
        });
    }
    getModalButtons(){
        return [
            <a href="javascript:;"
               className="btn btn-sm btn-danger">确定删除</a>

        ]
    }
    /**
     * 解散分组模态框展示
     */
    removeShow(){
        const {
            show,
        }=this.state;
        if(show){
            return(
                <DeleteBusiness title={ "解散分组" }
                                buttons={ this.getModalButtons() }
                                onClickCloseButton={ () => this.setState({
                                    show: false
                                }) }  >
                    <form className="form-horizontal">
                        <div className="form-group">
                            <label className="col-md-3 text-right m-0">名字</label>
                            <div className="col-md-8">
                                <p className="text_gray m-0">jshd</p>
                            </div>
                        </div>
                        <div className="form-group">
                            <label className="col-md-3 control-label">密码确认</label>
                            <div className="col-md-8">
                                <input type="password" className="form-control" placeholder="请输入您的登录密码" ref="passwordInput"/>
                            </div>
                        </div>
                    </form>
                </DeleteBusiness>
            )
        }else {
            return null;
        }
    }
    render(){
        return(
            <div id="page-container" className="page-container page-sidebar-fixed page-header-fixed">
                <div id="content" className="content">
                    <div>
                        <p>点击按钮感受一下弹出的对话框。</p>

                        <Button
                            bsStyle="primary"
                            bsSize="large"
                            onClick={()=>this.remove()}   >
                            弹出示例对话框
                        </Button>
                    </div>
                </div>
                {this.removeShow()}
            </div>

        )

    }
}
Modal.propTypes = propTypes;
export default Modal;

主页的代码很简单,在state中定义这个模态框展示的show属性,默认是false不展示模态框,点击改变属性值,不作过多的介绍,主要是模态框的实现。

一.自己实现Modal模态框

代码如下:

import React, { Component } from 'react';
import ReactDom from 'react-dom';
import PropTypes from 'prop-types';

import { VelocityTransitionGroup } from 'velocity-react';

import Util from 'util';

class DeleteBusiness extends Component {

    static propTypes = {
        title: PropTypes.string,
        buttons: PropTypes.array,

        onClickCloseButton: PropTypes.func
    };

    static defaultProps = {
        buttons: [],
        onClickCloseButton: () => {}
    };

    constructor(props) {
        super(props);

        Util.bindFunction([
            'hideModal'
        ], this);
    }

    hideModal() {

        $(this.popup).find('.fade.in').removeClass('in');
        setTimeout(() => {

            ReactDom.unmountComponentAtNode(this.popup);
            document.body.removeChild(this.popup);
            this.popup = null;
        }, 300);

        $('body').removeClass('modal-open')
    }

    componentWillMount() {
        const body = $('body');

        this.popup = document.createElement("span");
        body.append(this.popup);

        this.renderModal();

        body.addClass('modal-open');
    }

    componentWillUnmount() {
        this.hideModal();
    }

    renderModal() {

        const {
            title,
            buttons,
            children,
            onClickCloseButton
        } = this.props;

        const modal = (
            <div>
                <div className="modal-backdrop fade"></div>
                <div className="modal fade">
                    <div className="modal-dialog ">
                        <div className="modal-content">
                            <div className="modal-header">
                                <a href="javascript:;"
                                   onClick={ onClickCloseButton }
                                   className="close btn btn-xs btn-icon btn-circle btn-danger m-0"><i className="fa fa-times"></i></a>
                                <h4 className="modal-title">{ title }</h4>
                            </div>
                            <div className="modal-body">
                                { children }
                            </div>
                            <div className="modal-footer">
                                { buttons.map((btn, index) => React.cloneElement(btn, {
                                    key: ['PageModal', 'button', index].join('-')
                                })) }
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        );

        ReactDom.render(modal, this.popup, () => {
            const ls = $(this.popup).find('.fade').show();
            setTimeout(() => ls.addClass('in'), 10)
        });
    }
    
    render() {

        return null
    }
}

export default DeleteBusiness;

二.使用react-bootstrap中的Modal组件

代码如下:


import React, { Component } from 'react';
import ReactDom from 'react-dom';
import PropTypes from 'prop-types';
import {Modal,Button} from 'react-bootstrap';

import Util from 'util';

class DeleteBusiness extends Component {

    static propTypes = {
        title: PropTypes.string,
        buttons: PropTypes.array,

        onClickCloseButton: PropTypes.func,
        removeShowModal:PropTypes.string
    };

    static defaultProps = {
        buttons: [],
        onClickCloseButton: () => {}
    };

    constructor(props) {
        super(props);

        Util.bindFunction([
            'hideModal'
        ], this);
    }

    hideModal() {

        $(this.popup).find('.fade.in').removeClass('in');
        setTimeout(() => {

            ReactDom.unmountComponentAtNode(this.popup);
            document.body.removeChild(this.popup);
            this.popup = null;
        }, 300);

        $('body').removeClass('modal-open')
    }

    componentWillMount() {
        const body = $('body');

        this.popup = document.createElement("span");
        body.append(this.popup);
        body.addClass('modal-open');
    }

    componentWillUnmount() {
        this.hideModal();
    }

    render() {
        const {
            title,
            buttons,
            children,
            onClickCloseButton,
            removeShowModal
        } = this.props;
        return(
            <Modal show={removeShowModal} onHide={this.props.onClickCloseButton}>
                <Modal.Header closeButton>
                    <Modal.Title>{title}</Modal.Title>
                </Modal.Header>
                <Modal.Body>
                    { children }
                </Modal.Body>
                <Modal.Footer>
                    { buttons.map((btn, index) => React.cloneElement(btn, {
                        key: ['PageModal', 'button', index].join('-')
                    })) }
                </Modal.Footer>
            </Modal>
        )

    }
}

export default DeleteBusiness;

此时是将父组件是否显示模态框的state传过来的,所以主页代码调用模态框的组件时需要加个prop,

 <DeleteBusiness title={ "解散分组" }
                                buttons={ this.getModalButtons() }
                                onClickCloseButton={ () => this.setState({
                                    show: false
                                }) }
                                removeShowModal={this.state.show}>

                    <form className="form-horizontal">
                        <div className="form-group">
                            <label className="col-md-3 text-right m-0">名字</label>
                            <div className="col-md-8">
                                <p className="text_gray m-0">jshd</p>
                            </div>
                        </div>
                        <div className="form-group">
                            <label className="col-md-3 control-label">密码确认</label>
                            <div className="col-md-8">
                                <input type="password" className="form-control" placeholder="请输入您的登录密码" ref="passwordInput"/>
                            </div>
                        </div>
                    </form>
                </DeleteBusiness>
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,899评论 25 709
  • 今天上午组内小朋友们谈到 React 实践,提到 React 模态框(弹窗)的使用。我发现很多一些 React 开...
    LucasHC阅读 1,877评论 0 17
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,267评论 4 61
  • WebSocket-Swift Starscream的使用 WebSocket 是 HTML5 一种新的协议。它实...
    香橙柚子阅读 24,166评论 8 184
  • 对真核细胞祖先的追寻进入到了一个可怕的困境之中。可能存在一个初级的中间体,一个拥有细胞核却没有线粒体的缺失的一环的...
    鱼骨头段阅读 2,504评论 1 50