css 如何使LinearProgress MUI和SnackBar自动隐藏持续时间相同?

mzsu5hc0  于 2023-05-23  发布在  其他
关注(0)|答案(1)|浏览(98)

我需要用LinearProgress修复我的SnackBar,使其与4秒内设置的自动隐藏持续时间相匹配。我已经挣扎了好几个小时,但到目前为止我还没有找到一个合适的解决方案。有没有什么方法可以匹配自动隐藏持续时间和LinerProgress,使两者都持续4秒,然后snackBar自动关闭?我使用了MUI线性进度组件的代码。也许问题出在使用效果上?我是新来的,所以不是100%确定。谢谢你的建议!
这是我的代码:

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 [showLinearProgress, setShowLinearProgress] = useState(false);

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

  useEffect(() => {
    const timer = setInterval(() => {
      setProgress((oldProgress) => {
        if (oldProgress === 100) {
          return 0;
        }
        const diff = Math.random() * 15;
        return Math.min(oldProgress + diff, 100);
      });
    }, 400);
    return () => {
      clearInterval(timer);
    };
  }, []);

  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>
        {!showLinearProgress
         && <LinearProgress variant="determinate" sx={{ color:'#222221' }} value={progress} />}
      </div>
    </Snackbar>
    );
  };
uqxowvwt

uqxowvwt1#

我们首先需要找到:

  • 什么百分比是我们的进度条的步骤,因为我们传递给 prop 的值是0 - 100%的表示
  • 之后,我们可以添加此步骤,直到我们将条填充到100%,或者4秒的时间结束
  • 在间隔的开始,我们将小吃条状态设置为可见,在间隔的结束,我们将其设置回隐藏,同时将进度条的值重置为0

注意:有一个react库,我认为它对以后的问题会很有帮助

所以,这是我能够创建的:

const [snackbarVisibility, setSnackbarVisibility] = useState(false);
const [progress, setProgress] = useState(0);

const handleAction = () => {
  setSnackbarVisibility(true);

  // 10ms is what percentage(%) of 4000ms, equals to 0.25%
  const interval = setInterval(() => {
    setProgress((prevProgress) => prevProgress + 0.25);
  }, 10);
  
  // So, every 10ms we add 0.25 as a number to the value of the progress bar, until 4000ms/4s 
  // And since we calcualted the step, which is 0.25%, for 10ms of 4000ms, 
  // we can stop the progress bar and then hide the snack bar 
  // when the time of 4000ms lasts or when the value of the bar hits 100
  const duration = setTimeout(() => {
    clearInterval(interval);
    setSnackbarVisibility(false);
    setProgress(0);
  }, 4000);

  return () => {
    clearTimeout(duration);
  };
};

return (
  <>
    <Snackbar open={snackbarVisibility} />
    <LinearProgress
      value={progress}
      valueBuffer={progress}
      variant="determinate"
    />
    <Button onClick={handleAction}>Start</Button>
  </>
);

NB 2:当然,这可以进一步优化。
MUI Snackbar API
MUI LinerProgress API

相关问题