看了一下,上一篇文章还是1.1号写的,一恍二十多天过来了。轻易写一点react无关的货色吧,这一篇文章次要参考了https://www.cnblogs.com/demod...。
第一步:先写动态模版

src/component/Modal.tsximport React from 'react';import PropTypes from 'prop-types';import './Modal.css'interface ModalProps {    onOk: (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;    onCancel: (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;    title: string;    children: PropTypes.ReactElementLike;}export default class Modal extends React.Component<ModalProps> {    render() {        return (            <div className="modal-container">                <div className="modal-instance">                    <div className="modal-title">                        {this.props.title}                    </div>                    <div className="modal-content">                        {this.props.children}                    </div>                    <div className="modal-footer">                        <button onClick={this.props.onOk} className="button cancel-button">勾销</button>                        <button onClick={this.props.onCancel} className="submit submit-button">确认</button>                    </div>                </div>            </div>        )    }} 

款式轻易写写:

.modal-container {    position: fixed;    top: 0;    left: 0;    height: 100%;    width: 100%;    background-color:rgba(4,4,4, 0.45);}.modal-instance {    position: absolute;    top: 50%;    left: 50%;    background-color: #ffffff;    transform: translate(-50%, -50%);    border-radius: 3px;    border-style: 1px solid #353535;}.modal-title {    height: 20px;    width: 100%;    min-width: 500px;    font-size: 16px;    font-weight: 500;    display: flex;    align-items: center;}.modal-content {    padding: 5px;}.modal-footer {    height: 30px;    font-size: 14px;    display: flex;    align-items: center;}

当初开始调用modal:

class Game extends React.Component<Props, TestState> {  constructor(props: Props) {    super(props);    this.state = {      isShowModal: false    }  }  openModal = () => {    this.setState({      isShowModal: true    })  }  render() {    const ModalProps = {      onOk: (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {},      onCancel:(event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {},      title: '测试modal',    }    const { isShowModal } = this.state;     return (<>             {isShowModal && <Modal {...ModalProps}>          <div>            {'modal content'}          </div>        </Modal>}        <button onClick={this.openModal}>弹出modal框</button>      </>    );

当初为止咱们实现了一个简略的动态的modal弹框。当初咱们心愿提供更多的调用形式,比方我心愿应用ModalService.open(template, {onOk: () => {}, onCancel: () => {}})这种api进行调用。那咱们就须要进行封装:

export class ModalService {    static open(props: ModalProps) {        const modalContainer = document.createElement('div');        document.body.appendChild(modalContainer);        function onOk() {            props.onOk();            ReactDOM.unmountComponentAtNode(modalContainer);        }        function onCancel() {            props.onCancel();            ReactDOM.unmountComponentAtNode(modalContainer);        }        ReactDOM.render(<Modal {...props} onOk={onOk} onCancel={onCancel} />, modalContainer);    }}

当初咱们来测试一下ModalService.open的调用弹框形式

  openModalService = () => {    const inputNameChange = (event: React.ChangeEvent<HTMLInputElement>) => {      this.setState({        inputName: event.target.value      });    }    ModalService.open({      onOk: () => {        console.log(this.state.inputName);        console.log('modal submit ???? by service, and close')      },      onCancel: () => {        this.setState({          inputName: ''        })        console.log('modal cancel ❌ by service, and close')      },      title: '这是service关上的',      children: (<input type="text" value={this.state.inputName} onChange={inputNameChange} />)    })  }

这里其实有个bug,这里的input弹框绑定了value={this.state.inputName} 来绑定,然而其实这个element并没有真正的实现数据绑定,因为他只是创立了一次,并没有和render函数关联所以会呈现,任何对input文本框的输出,都看不到的状况。所以在有输出模版为form的状况下,更好的形式是应用组件调用,在render中应用组件调用的形式。

        {isShowModal && <Modal {...ModalProps}>          <div>            {'modal content'}            <input type="text" value={this.state.inputNameStash} onChange={this.inputNameChange} />          </div>        </Modal>}

相似这样写。或者modalservice.open的形式关上一个render办法中定义的ref。然而这样如同不太合乎react哲学(so?
最初封装一个链式调用的api吧。
1.先革新modalservice使他返回一个promise

export class ModalService {    static open(props: ModalProps) {        const modalContainer = document.createElement('div');        document.body.appendChild(modalContainer);                return new Promise<void>((resolve, reject) => {            function onOk() {                props.onOk && props.onOk();                ReactDOM.unmountComponentAtNode(modalContainer);                resolve();            }            function onCancel() {                props.onCancel && props.onCancel();                ReactDOM.unmountComponentAtNode(modalContainer);                reject();            }            ReactDOM.render(<Modal {...props} onOk={onOk} onCancel={onCancel} />, modalContainer);        })    }}

调用形式改为:

    openModalServicePromise = async () => {        ModalService.open({            title: '期待返回promise进行链式调用',            children: '这是期待的promise返回的格局,这样更好用感觉'        }).then(() => {            console.log('modal 点击了确定✅, and close')        }).catch(() => {            console.log('modal 点击了勾销????️, and close')        })    }

几乎perfect!