Created
April 2, 2019 08:43
-
-
Save varHarrie/ad708b372560989c9b86cbc2b8b1da35 to your computer and use it in GitHub Desktop.
React Solutions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as React from 'react' | |
/** | |
* 通过调用createModal函数,传入一个模态窗口组件,返回对象{ show: [Function], hide: [Function], Component: [React.Component] } | |
* | |
* @example: | |
* class App extends React.Component { | |
* modal = createModal(SomeModalComponent) | |
* | |
* render () { | |
* return ( | |
* <div> | |
* <button onClick={() => this.modal.show('标题')}>show</button> | |
* <this.modal.Component/> | |
* </div> | |
* ) | |
* } | |
* } | |
* | |
* @description: | |
* - modal.show函数用于显示窗口 | |
* - modal.hide函数用于隐藏窗口 | |
* - modal.Component为窗口组件 | |
*/ | |
/** 模态窗口组件属性 */ | |
export type ModalComponentProps<O> = { | |
title: string | |
visible: boolean | |
onOk: (output: O) => any | |
onCancel: () => any | |
} | |
/** 模态窗口组件类型 */ | |
export type ModalComponentType<O, I extends ModalComponentProps<O>> = React.ComponentType<I> | |
/** 模态窗口组件自有属性(除去ModalComponentProps的剩余属性) */ | |
type ModalOwnProps<P> = Pick<P, Exclude<keyof P, keyof ModalComponentProps<any>>> | |
/** 模态窗口回调 */ | |
type ModalCallback<O> = (output: O) => any | Promise<any> | |
/** 包装组件内部状态 */ | |
interface WrapperState<I> { | |
title: string | |
visible: boolean | |
input?: I | |
} | |
/** 创建模态窗口 */ | |
export default function createModal<O = any, I extends ModalComponentProps<O> = any> ( | |
OriginalComponent: ModalComponentType<O, I> | |
) { | |
let instance: any = null | |
return { | |
show (title: string, props: ModalOwnProps<I>, callback: ModalCallback<O>) { | |
if (instance) instance.show(title, props, callback) | |
}, | |
hide () { | |
if (instance) instance.hide() | |
}, | |
Component: class extends React.Component<any, WrapperState<I>> { | |
private callback?: ModalCallback<O> | |
public constructor (props: any) { | |
super(props) | |
if (instance) { | |
console.warn('同一个模态窗口组件只能有一个实例') | |
} else { | |
instance = this | |
} | |
this.state = { | |
title: '', | |
visible: false | |
} | |
} | |
// 显示,将传入参数作为当前实例的内部状态 | |
public show = (title: string, input: any, callback: ModalCallback<O>) => { | |
this.setState({ visible: true, title, input }) | |
this.callback = callback | |
} | |
// 关闭 | |
public hide = () => { | |
this.setState({ visible: false }) | |
} | |
// 确定,并调用回调函数,根据结果判断是否关闭窗口 | |
// 若该回调函数返回true,阻止关闭窗口,否则关闭窗口 | |
private onConfirm = (output: O) => { | |
let result = this.callback ? this.callback(output) : true | |
if (!(result instanceof Promise)) result = Promise.resolve(result) | |
result.then((r: any) => !!r === false && this.hide()) | |
} | |
// 取消,并关闭窗口 | |
private onCancel = () => { | |
this.hide() | |
} | |
// 渲染,传入状态和事件 | |
public render () { | |
const { visible, input } = this.state | |
const props: any = { ...this.props, visible, onHide: this.hide } | |
return <OriginalComponent {...input} {...props} onOk={this.onConfirm} onCancel={this.onCancel} /> | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment