Files
DataMate/frontend/src/components/TopLoadingBar.tsx
Jerry Yan accaa47a83 fix(components): 修复组件中定时器内存泄漏问题
- 在TopLoadingBar组件中添加timeoutRef并正确清理定时器
- 在Agent页面中添加timeoutRef管理AI响应模拟定时器
- 修复BasicInformation组件中useCallback依赖数组缺失问题
- 在CreateDataset页面中传递hidden属性控制数据源显示
- 在Orchestration页面中添加intervalRef管理工作流执行进度
- 在SynthesisTask中添加testTimeoutRef管理模板测试定时器
- 确保所有组件卸载时正确清除定时器避免内存泄漏
2026-01-30 14:35:45 +08:00

79 lines
2.0 KiB
TypeScript

import { useEffect, useRef, useState } from "react";
const TopLoadingBar = () => {
const [isVisible, setIsVisible] = useState(false);
const [progress, setProgress] = useState(0);
const intervalRef = useRef(null);
const timeoutRef = useRef(null);
useEffect(() => {
// 监听全局事件
const handleShow = () => {
setIsVisible(true);
setProgress(0);
// 清除可能存在的旧interval
if (intervalRef.current) {
clearInterval(intervalRef.current);
}
// 模拟进度
let currentProgress = 0;
intervalRef.current = setInterval(() => {
currentProgress += Math.random() * 10;
if (currentProgress >= 90) {
clearInterval(intervalRef.current);
}
setProgress(currentProgress);
}, 200);
};
const handleHide = () => {
// 清除进度interval
if (intervalRef.current) {
clearInterval(intervalRef.current);
intervalRef.current = null;
}
// 清除旧的timeout
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
timeoutRef.current = null;
}
setProgress(100);
timeoutRef.current = setTimeout(() => {
setIsVisible(false);
setProgress(0);
}, 300);
};
// 添加全局事件监听器
window.addEventListener("loading:show", handleShow);
window.addEventListener("loading:hide", handleHide);
return () => {
// 组件卸载时清理
if (intervalRef.current) {
clearInterval(intervalRef.current);
}
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
window.removeEventListener("loading:show", handleShow);
window.removeEventListener("loading:hide", handleHide);
};
}, []);
if (!isVisible) return null;
return (
<div className="top-loading-bar">
<div
className="loading-bar-progress"
style={{ width: `${progress}%` }}
></div>
</div>
);
};
export default TopLoadingBar;