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

如何让MUI LinearProgress与SnackBar自动隐藏时长保持一致?

解决方案:让SnackBar和LinearProgress同步4秒时长

要实现两者精准同步4秒后关闭,核心是让进度条在4秒内匀速从0走到100%,并且和SnackBar的自动关闭逻辑对齐。你原代码的问题在于进度更新是随机增量,且没有和SnackBar的打开状态联动,下面是修改后的代码和关键说明:

关键修改点

  • 绑定进度条定时器到open状态,只有SnackBar打开时才启动
  • 计算匀速进度增量,确保4秒内刚好完成100%(比如每40ms增加1%,40*100=4000ms)
  • 进度到100%时触发SnackBar关闭,同时清理定时器
  • 简化进度条的显示逻辑,直接根据open状态控制

修改后的完整代码

interface SuccessMessageProps {
  open: boolean;
  onClose: () => void;
  title?: string;
  message?: string;
}

const SlideTransition = (props: SlideProps) => <Slide {...props} direction="left" />;

export const SuccessMessage = ({
  open,
  onClose,
  title = 'Title',
  message = 'Insert message here'
}: SuccessMessageProps) => {
  const { palette } = useTheme();
  const [progress, setProgress] = useState(0);

  const handleClose = (): void => {
    onClose();
  };

  useEffect(() => {
    let timer: NodeJS.Timeout;
    if (open) {
      // 打开时重置进度为0
      setProgress(0);
      // 每40ms增加1%,4秒刚好走完100%
      timer = setInterval(() => {
        setProgress((old) => {
          const newProgress = old + 1;
          if (newProgress >= 100) {
            clearInterval(timer);
            // 进度完成后关闭SnackBar
            handleClose();
            return 100;
          }
          return newProgress;
        });
      }, 40);
    }
    return () => {
      if (timer) clearInterval(timer);
    };
  }, [open]);

  return (
    <Snackbar
      open={open}
      autoHideDuration={4000}
      anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
      TransitionComponent={SlideTransition}
      onClose={handleClose}
    >
      <div>
        <Alert
          sx={{
            width: '487px',
            height: '104px',
            paddingTop: '20px',
            paddingLeft: '20px',
            backgroundColor: '#FDFDFD',
          }}
          icon={
            <Stack
              justifyContent="center"
              alignItems="center"
              style={{
                borderRadius: '100%',
                backgroundColor: alpha(palette.success.main, 0.10),
                width: '48px',
                height: '48px',
              }}
            >
              <CheckIcon size={24} color={palette.success.main} />
            </Stack>
          }
          onClose={handleClose}
        >
          <AlertTitle sx={{ paddingRight: '80px' }}>
            <Typography variant='headings.h4'>{title}</Typography>
          </AlertTitle>
          <Typography variant='captions.default'>{message}</Typography>
        </Alert>
        {/* SnackBar打开时显示进度条 */}
        {open && <LinearProgress variant="determinate" sx={{ color: '#222221' }} value={progress} />}
      </div>
    </Snackbar>
  );
};

额外说明

  • 保留autoHideDuration={4000}作为兜底,防止进度条逻辑意外失败时SnackBar仍能自动关闭
  • 匀速更新进度条,视觉上更协调,也能精准匹配4秒时长
  • 每次SnackBar打开都会重置进度,避免重复打开时进度残留

内容的提问来源于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 09:15:03