需求
- 彈窗出現時,固定在屏幕中間
- 彈窗中標題、內容文字自定義
- 取消按鈕可選
- 點擊關閉按鈕,彈窗消失
- 點擊確定,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