MUI Dialog封装问题:无法将onClose传递给弹窗操作区内按钮的onClick事件
问题原因
MUI 内置 DialogProps 定义的 onClose 函数签名和 Button 组件的 onClick 期望的函数签名不匹配:
- Dialog 的
onClose类型为:(event: {}, reason: "backdropClick" | "escapeKeyDown") => void,是给对话框背景点击、ESC 键按下这类关闭场景触发用的 - Button 的
onClick期望的是鼠标事件处理函数,类型为:(event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void
直接透传会触发 TS 类型校验失败,除此之外你自定义的handleClose要求接收 string 类型参数,也和默认的 Dialog onClose 类型不兼容。
解决方案
步骤1:调整封装的 Dialog 组件
单独处理按钮点击的关闭逻辑,不要直接把 Dialog 的 onClose 透传给 Button 的 onClick,同时扩展 props 兼容你自定义的传参需求:
import React from 'react'; import { Dialog as MuiDialog, DialogProps, Button, DialogContent, DialogActions, DialogTitle, } from '@material-ui/core'; // 扩展原有DialogProps,兼容自定义关闭参数 interface CustomDialogProps extends Omit<DialogProps, 'onClose'> { onClose: (value?: string) => void; title?: string; } const Dialog = ({ title, open, onClose, children, ...props }: CustomDialogProps) => { // 单独处理关闭按钮的点击事件 const handleBtnClose = () => { // 这里可以传你需要的自定义参数,比如空字符串、或者自定义的返回值 onClose('close-btn-click'); }; return ( <MuiDialog onClose={(_, reason) => { // 处理背景点击、ESC关闭的场景,你可以根据需要传对应的参数 onClose(reason); }} aria-labelledby='simple-dialog-title' open={open} {...props} > <DialogTitle id='simple-dialog-title'>{title}</DialogTitle> <DialogContent>{children}</DialogContent> <DialogActions> <Button onClick={handleBtnClose} color='primary'> Close </Button> </DialogActions> </MuiDialog> ); };
步骤2:对齐使用侧的 handleClose 类型
const SimpleDialogDemo = () => { const [open, setOpen] = React.useState(false); const handleClickOpen = () => { setOpen(true); }; // 参数类型和封装组件的onClose对齐 const handleClose = (value?: string) => { console.log('关闭来源:', value); // 可以拿到是按钮点击、背景点还是ESC触发的关闭 setOpen(false); }; return ( <div> <br /> <Button variant='outlined' color='primary' onClick={handleClickOpen}> Open simple dialog </Button> <Dialog open={open} onClose={handleClose} title="测试对话框" children={<div>Test</div>} /> </div> ); }
可选简化方案
如果你不需要区分关闭来源、也不需要传自定义参数,也可以直接在绑定Button onClick的时候用箭头函数包一层,跳过类型校验,适合快速开发场景:
<Button onClick={() => onClose?.()} color='primary'> Close </Button>
内容的提问来源于stack exchange,提问作者Kareem Abdelwahed
相关产品推荐
相关产品推荐

