以下為一個常見的 React 對話框元件( 範例取自 React Bootstrap、Material UI ),我們通常會在元件內建立一組local state 控制 對話框的開、關,同時一起渲染出 開啟對話窗的按鈕 跟 Modal。
假設今天我們希望這個 <Modal>
不是點 <Button>
被觸發,而是點 <img>
被觸發,這樣我們是不是又要再多寫一個元件出來? 但 <Modal>
內部的行為與樣式都是一致的。
這樣是否代表我們希望外部點擊的元件不同時,我們就要寫出許多只差 2~3 行不一樣 Modal?
我們有沒有辦法在使用這個 Modal的外面,決定要點擊的元件是什麼?
<Button variant="primary" onClick={handleShow}>
Launch demo modal
</Button>
底下 modal 一樣 ...
<img src={image} onClick={handleShow} />
底下 modal 一樣 ...
export default function BootstrapModalExample() {
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
return (
<>
{/* ---------------------- 開啟對話窗的按鈕 ---------------------- */}
<Button variant="primary" onClick={handleShow}>
Launch demo modal
</Button>
{/* ---------------------- 開啟對話窗的按鈕 ---------------------- */}
{/* ------------------------- Modal --------------------------- */}
<Modal show={show} onHide={handleClose}>
<Modal.Header closeButton>
<Modal.Title>Modal heading</Modal.Title>
</Modal.Header>
<Modal.Body>Woohoo, you're reading this text in a modal!</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={handleClose}>
Close
</Button>
<Button variant="primary" onClick={handleClose}>
Save Changes
</Button>
</Modal.Footer>
</Modal>
{/* ------------------------- Modal --------------------------- */}
</>
);
}
export default function MateriaUIAlertDialog() {
const [open, setOpen] = React.useState(false);
const handleClickOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
return (
<div>
{/* ---------------------- 開啟對話窗的按鈕 ---------------------- */}
<Button variant="outlined" color="primary" onClick={handleClickOpen}>
Open alert dialog
</Button>
{/* ---------------------- 開啟對話窗的按鈕 ---------------------- */}
{/* ------------------------- Modal --------------------------- */}
<Dialog
open={open}
onClose={handleClose}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitle id="alert-dialog-title">{"Use Google's location service?"}</DialogTitle>
<DialogContent>
<DialogContentText id="alert-dialog-description">
Let Google help apps determine location. This means sending anonymous location data to
Google, even when no apps are running.
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={handleClose} color="primary">
Disagree
</Button>
<Button onClick={handleClose} color="primary" autoFocus>
Agree
</Button>
</DialogActions>
</Dialog>
{/* ------------------------- Modal --------------------------- */}
</div>
);
}