MUI中Snackbar内嵌Alert无法通过关闭图标关闭求助
问题分析
你的代码核心问题是Snackbar的open属性绑定的是父组件传入的props.open,但点击关闭按钮时只修改了内部的openMessage状态,这两个状态没有关联,所以Snackbar不会响应内部状态的变化而关闭。另外还存在一个拼写错误:setOpenMesage应该是setOpenMessage(少了一个s),虽然不影响当前问题,但会导致后续状态更新出错,建议修正。
解决方案
根据组件的使用场景,有两种修复方式:
方式一:受控组件(推荐,适合父组件需要控制提示显示/隐藏的场景)
如果InfoMessage是由父组件控制显示的,需要通过回调函数通知父组件修改open状态,而非依赖内部状态:
import { useState } from 'react'; import CloseIcon from '@mui/icons-material/Close'; import { Alert, AlertTitle, IconButton, Snackbar, Typography } from '@mui/material'; interface InfoMessageProps { open: boolean; onClose: () => void; // 新增回调属性,通知父组件关闭 } export const InfoMessage = ({ open, onClose }: InfoMessageProps) => { const handleCloseMessage = (): void => { onClose(); // 调用父组件的关闭方法 }; return ( <Snackbar open={open} autoHideDuration={4000} anchorOrigin={{ vertical: 'top', horizontal: 'right' }} onClose={handleCloseMessage} > <Alert sx={{ width: '487px', height: '104px', paddingTop: '20px', paddingLeft: '20px', backgroundColor: '#FDFDFD', }} icon={false} action={( <IconButton aria-label="close" color="inherit" size="small" onClick={handleCloseMessage} > <CloseIcon fontSize="inherit" /> </IconButton> )} > <AlertTitle sx={{ paddingRight:'80px' }}> <Typography variant='headings.h4'>title</Typography> </AlertTitle> <Typography variant='captions.default'>Insert message here</Typography> </Alert> </Snackbar> ); };
父组件使用时需传递onClose回调:
// 父组件示例 const ParentComponent = () => { const [showSnackbar, setShowSnackbar] = useState(true); return ( <div> <InfoMessage open={showSnackbar} onClose={() => setShowSnackbar(false)} /> </div> ); };
方式二:不受控组件(适合组件内部自行控制显示/隐藏的场景)
如果不需要父组件控制,直接在组件内部维护状态,将Snackbar的open绑定到内部状态,同时可通过props的open初始化状态:
import { useState, useEffect } from 'react'; import CloseIcon from '@mui/icons-material/Close'; import { Alert, AlertTitle, IconButton, Snackbar, Typography } from '@mui/material'; interface InfoMessageProps { open?: boolean; // 改为可选,作为初始化状态 } export const InfoMessage = ({ open = false }: InfoMessageProps) => { const [openMessage, setOpenMessage] = useState(open); // 同步父组件传入的open状态变化 useEffect(() => { setOpenMessage(open); }, [open]); const handleCloseMessage = (): void => { setOpenMessage(false); }; return ( <Snackbar open={openMessage} // 绑定内部状态 autoHideDuration={4000} anchorOrigin={{ vertical: 'top', horizontal: 'right' }} onClose={handleCloseMessage} > <Alert sx={{ width: '487px', height: '104px', paddingTop: '20px', paddingLeft: '20px', backgroundColor: '#FDFDFD', }} icon={false} action={( <IconButton aria-label="close" color="inherit" size="small" onClick={handleCloseMessage} > <CloseIcon fontSize="inherit" /> </IconButton> )} > <AlertTitle sx={{ paddingRight:'80px' }}> <Typography variant='headings.h4'>title</Typography> </AlertTitle> <Typography variant='captions.default'>Insert message here</Typography> </Alert> </Snackbar> ); };
额外提示
Snackbar的onClose事件会在自动隐藏时触发,绑定handleCloseMessage可以让自动隐藏也能正确关闭提示。
内容的提问来源于stack exchange,提问作者mariadev
相关产品推荐
相关产品推荐

