fix: Tab切换延迟渲染重内容,解决区域页切换卡顿
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

- 切换Tab时先卸载旧内容显示loading,下一帧再渲染新内容
- 图表等重组件不再阻塞Tab切换动画
- 所有Tab统一处理,切换体验一致

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
kkfluous
2026-03-29 00:35:07 +08:00
parent 799d00b3da
commit 189098cd54

View File

@@ -1,4 +1,4 @@
import React, { useState, useEffect, useCallback, useMemo, useRef, useTransition } from 'react';
import React, { useState, useEffect, useCallback, useMemo, useRef } from 'react';
import {
Truck,
Warehouse,
@@ -114,9 +114,17 @@ const TABS = [
];
export default function App() {
const [activeTab, setActiveTabRaw] = useState<'overview' | 'department' | 'region' | 'customer'>('overview');
const [, startTransition] = useTransition();
const setActiveTab = useCallback((tab: typeof activeTab) => { startTransition(() => setActiveTabRaw(tab)); }, []);
const [activeTab, setActiveTab] = useState<'overview' | 'department' | 'region' | 'customer'>('overview');
const [tabReady, setTabReady] = useState(true);
const prevTabRef = useRef(activeTab);
useEffect(() => {
if (prevTabRef.current !== activeTab) {
setTabReady(false);
prevTabRef.current = activeTab;
const id = requestAnimationFrame(() => { setTabReady(true); });
return () => cancelAnimationFrame(id);
}
}, [activeTab]);
const [theme, setTheme] = useState<'soft' | 'minimal' | 'vibrant'>('soft');
const [expandedModels, setExpandedModels] = useState<Set<string>>(new Set());
const [expandedAssetTypes, setExpandedAssetTypes] = useState<Set<string>>(new Set());
@@ -613,7 +621,13 @@ export default function App() {
{/* Main Content Area */}
<div className="flex flex-col gap-6">
{activeTab === 'overview' && (
{!tabReady && (
<div className="flex items-center justify-center py-20">
<Loader2 className="animate-spin text-blue-500" size={28} />
</div>
)}
{tabReady && activeTab === 'overview' && (
<>
{/* Header Summary - Ultra Compact */}
<div className="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 gap-2 mb-2">
@@ -1384,7 +1398,7 @@ export default function App() {
</>
)}
{activeTab === 'department' && (
{tabReady && activeTab === 'department' && (
<section className="bg-white rounded-2xl shadow-sm border border-gray-100 overflow-hidden mb-6">
<div className="p-0 sm:p-2 bg-gray-50/30">
{/* Overall Total Summary (Compact) - Moved to Top */}
@@ -1901,7 +1915,7 @@ export default function App() {
</section>
)}
{activeTab === 'region' && (
{tabReady && activeTab === 'region' && (
<div className="flex flex-col gap-6">
{/* Region Distribution Chart */}
<section className="bg-white rounded-2xl shadow-sm border border-gray-100 p-4 sm:p-6">
@@ -2175,7 +2189,7 @@ export default function App() {
</div>
)}
{activeTab === 'customer' && (
{tabReady && activeTab === 'customer' && (
<div className="flex flex-col gap-6">
{/* Customer Region Distribution Chart */}
<section className="bg-white rounded-2xl shadow-sm border border-gray-100 p-4 sm:p-6">