需求
- 弹窗出现时,固定在屏幕中间
- 弹窗中标题、内容文字自定义
- 取消按钮可选
- 点击关闭按钮,弹窗消失
- 点击确定,Resolve 函数被执行,弹窗消失
- 该弹窗采用一个函数形式被调用,返回一个Promise, 在then 中执行确定后的逻辑
弹窗设计
鉴于以上需求,将整个弹窗拆分为一个UI组件(Dialog),一个处理函数部分(Staticize)
Dialog
Props
- title:弹窗标题
- message:内容信息
- onConfirm: 确认时调用的函数,
- onCancel:点击关闭或取消时,调用的函数
import React from 'react'
import cx from 'classnames'
import SVGIcon from 'components/SVGIcon'
import styles from './Dialog.scss'
const Dialog = ({
title,
message,
onConfirm,
onCancel,
}) => (
<div className={styles.root}>
<div className={styles.header}>
<SVGIcon
className={styles.icon}
name="dialog/warning"
width="32"
height="32"
/>
<div className={styles.title}>{title}</div>
</div>
<div className={styles.message}>{message}</div>
<div className={styles.buttons}>
<button className={styles.button} onClick={onCancel}>
取消
</button>
<button className={cx(styles.button, styles.active)} onClick={onConfirm}>
确定
</button>
</div>
</div>
)
export default Dialog
Staticize
Props
- title:弹窗标题
- message:内容信息
函数行为
- 返回一个Promise 对象,接收一个 fullfill
作为 Resolve 时参数。 - 创建一个div, 并添加到 body 中,在该 div 中渲染出 Dialog。
- close 函数移除该 div, 并作为Dialog 的 onCancel 属性
- onConfirm 中 执行 fullfill 和 close
import React from 'react'
import ReactDOM from 'react-dom'
import Dialog from './Dialog'
const staticize = props =>
new Promise((fulfill) => { // 此处参数需用圆括号,否则 eslint 报错
const holder = document.createElement('div')
document.body.appendChild(holder)
const close = () => {
document.body.removeChild(holder)
}
ReactDOM.render(
<Dialog
{...props}
onCancel={close}
onConfirm={() => {
close()
fulfill()
}}
/>,
holder
)
})
export default staticize