背景

项目中经常会遇到这种情况,调用A接口之后需要有一个确认弹框。用户点击确认之后再调用B接口。
确认弹框如果使用 visible 来控制的话,那么势必会将一个同步的流程变成异步的处理。我们可能需要保存当前的执行环境。
所以命令式的弹框很有必要可以让整个流程如流水线般的一条线下来,不用再通过 visible 来响应式的控制弹框

用法

jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const ModalView: FC<{
visible
}> = () => {
return (
<Modal visible={visible}>
<div>这是弹框的内容</div>
</Modal>
)
}

// 命令式调用,这样就能快速唤起 ModalView 弹框
const modalView = new ModalViewUtils(ModalView)
modalView.show({
visible: true
})

源码

jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

import React from 'react'
import { createRoot, Root } from 'react-dom/client'

interface IProps extends AnyObject {
onClose?: (params?: any) => void
onVisibleChange?: boolean
}

/**
* 将 Modal 变为命令式调用的通用方法
*/
class ModalViewUtils<T extends IProps> {
private div: HTMLDivElement | null = null
private Component: any
private root: Root | undefined = undefined

constructor(Component: any) {
this.Component = Component
}

close(props: T | undefined, params?: any) {
if (this.root && this.div) {
this.root.unmount()
if (this.div.parentNode) {
this.div.parentNode.removeChild(this.div)
}
props?.onClose?.(params)
}
}

show(props?: T) {
this.div = document.createElement('div')
document.body.append(this.div)
const ModalComponent = this.Component
const onClose = (params?: any) => {
this.close(props, params)
}

const onOk = (params?: any) => {
if (props?.onOk) {
props.onOk(params)
}
this.close(props)
}

this.root = createRoot(this.div)
this.root.render(<ModalComponent {...props} onOk={onOk} onClose={onClose} />)
return onClose
}
}

export default ModalViewUtils