17370845950

解决 Material-UI Snackbar 进度条无法到达终点的问题

本文针对 Material-UI Snackbar 组件中进度条在消息关闭前无法到达终点的问题,提供了一种解决方案。通过调整进度判断逻辑,考虑 CSS 过渡动画的延迟,确保进度条在消息显示结束时能够完整显示,从而提升用户体验。

在使用 Material-UI 的 Snackbar 组件时,如果需要展示一个进度条,可能会遇到进度条在消息关闭前无法到达终点的问题。这通常是由于进度更新的频率与 Snackbar 的关闭时间不匹配,以及 CSS 过渡动画的延迟导致的。以下提供一种解决方案,通过调整进度判断逻辑,来解决这个问题。

问题分析

Material-UI 的 LinearProgress 组件具有一个默认的 CSS 过渡动画,这意味着当进度值发生变化时,进度条的显示不会立即更新,而是会有一个过渡效果。如果 Snackbar 的关闭时间与进度条的过渡时间相近,就可能出现进度条未到达终点就被关闭的情况。

解决方案

解决方案的核心在于,在判断进度是否完成时,考虑到 CSS 过渡动画的延迟。具体来说,可以适当增加进度判断的阈值,使其超过 100%。

代码示例

假设你的 GenericSnackbarMessage 组件中,使用 useEffect 来更新进度条的进度,并使用 setInterval 定时器来触发更新。以下是修改后的代码片段:

useEffect(() => {
  if (!closeMessageAfterTime || !activeTimer || !isLastElement) return;

  const startTime = Date.now();
  const duration = 4000;

  const updateProgress = (): void => {
    const currentTime = Date.now();
    const elapsedTime = currentTime - startTime;
    const innerProgress = elapsedTime / duration * 100;

    setProgress(innerProgress >= 100 ? 100 : innerProgress);

    // 关键修改:将判断条件从 innerProgress >= 100 改为 innerProgress >= 110
    if (innerProgress >= 110 && elapsedTime >= duration) {
      console.log('Progress at timer end:', innerProgress);
      handleClose();
    }
  };

  const timerId = setInterval(updateProgress, 100);

  return (): void => {
    clearInterval(timerId);
  };
}, [closeMessageAfterTime, activeTimer, isLastElement, handleClose]);

代码解释

  1. 增加进度判断阈值: 将 if (innerProgress >= 100 && elapsedTime >= duration) 修改为 if (innerProgress >= 110 && elapsedTime >= duration)。这意味着,只有当进度条的计算值超过 110% 时,才会触发 Snackbar 的关闭。

  2. 原因: Material-UI 的 LinearProgress 组件默认具有 0.4 秒(400 毫秒)的过渡动画。如果 Snackbar 的显示时间为 4 秒(4000 毫秒),那么总共需要 4.4 秒(4400 毫秒)才能保证进度条完全到达终点。因此,将进度判断阈值设置为 110% 可以有效地解决这个问题。

注意事项

  • 过渡时间: 上述解决方案基于 Material-UI LinearProgress 组件默认的 0.4 秒过渡时间。如果你的项目修改了过渡时间,需要相应地调整进度判断阈值。

  • 实际效果: 由于过渡动画的存在,进度条的实际显示可能会略有延迟。你可以根据实际情况调整进度判断阈值,以达到最佳效果。

  • 兼容性: 在修改进度判断逻辑时,需要确保不会影响其他功能或组件的正常运行。

总结

通过调整进度判断逻辑,并考虑到 CSS 过渡动画的延迟,可以有效地解决 Material-UI Snackbar 进度条无法到达终点的问题。这种方法简单易行,能够提升用户体验,确保进度条在消息显示结束时能够完整显示。在实际应用中,可以根据项目的具体情况进行适当调整,以达到最佳效果。