React使用setTimeout控制ProgressBar最少显示500ms的问题排查
现有代码问题汇总
- useEffect依赖为空,无法监听到
props.loadingStatus.state的后续更新,定时器逻辑只会在组件挂载时执行一次,服务端状态变化后不会触发对应更新 - 闭包陷阱:定时器内拿到的
LoadStat和props.loadingStatus.state永远是组件首次挂载时的初始值,和最新状态不一致 - 进度条显示逻辑错误:当前只要
LoadStat不为空就会显示进度条,不管状态是Not Started、Running还是Completed,这是进度条持续不消失的核心原因 - 状态判断语法错误:
LoadStat === Running中的Running是未定义变量,应该用字符串取值'Running'匹配服务端返回的枚举值 - 缺少定时器清理逻辑,组件卸载或状态快速变化时会触发内存泄漏、旧定时器执行导致的状态异常
修复方案
修复后的逻辑会同时跟踪两个状态:服务端返回的最新加载状态、进度条最短500ms显示时间是否已走完,仅当状态为Running,或状态已变为Completed但最短显示时间还没到的时候展示进度条,代码如下:
const App = (props) => { // 同步服务端返回的最新加载状态 const [serverLoadState, setServerLoadState] = React.useState(props.loadingStatus.state); // 标记进度条最短500ms显示时间是否已结束 const [isMinDisplayTimePassed, setIsMinDisplayTimePassed] = React.useState(false); React.useEffect(() => { // 同步最新的服务端加载状态 const latestState = props.loadingStatus.state; setServerLoadState(latestState); let timer = null; // 当状态切换为Running时,启动计时 if (latestState === 'Running') { // 重置时间标记 setIsMinDisplayTimePassed(false); timer = setTimeout(() => { setIsMinDisplayTimePassed(true); }, 500); } // 清理定时器,避免状态快速切换、组件卸载时的异常 return () => { if (timer) clearTimeout(timer); }; // 依赖添加props.loadingStatus.state,状态变化时重新触发逻辑 }, [props.loadingStatus.state]); // 进度条显示条件:状态为Running,或者状态已完成但最短显示时间还没到 const showProgressBar = serverLoadState === 'Running' || (serverLoadState === 'Completed' && !isMinDisplayTimePassed); return ( <> {showProgressBar && ( <ProgressBar minValue={0} maxValue={100} progress={percentage} /> )} </> ); }
内容的提问来源于stack exchange,提问作者hightides1973
相关产品推荐
相关产品推荐

