You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 12:37:46