perf(HotspotOverview): 日期切换时只刷新图表,不重新渲染整个模块

- useHotspotData 新增 refreshing 状态,区分首次加载和切换日期
- 首次加载显示全屏 loading,切换日期仅显示图表区域加载指示器
- 避免日期切换时整体布局闪烁

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
zdl
2025-12-31 14:43:44 +08:00
parent 494d9c8918
commit df3d502862

View File

@@ -11,13 +11,18 @@ import { getApiBase } from '@utils/apiConfig';
* @returns {Object} 数据和状态
*/
export const useHotspotData = (selectedDate) => {
// 首次加载状态(仅在初始化时为 true
const [loading, setLoading] = useState(true);
// 刷新状态(切换日期时为 true不影响整体布局
const [refreshing, setRefreshing] = useState(false);
const [error, setError] = useState(null);
const [data, setData] = useState(null);
// 用于防止 React StrictMode 下的双重请求
const fetchingRef = useRef(false);
const lastDateRef = useRef(null);
// 是否已完成首次加载
const initializedRef = useRef(false);
const fetchData = useCallback(async (forceRefetch = false) => {
// 获取日期字符串用于比较
@@ -29,14 +34,20 @@ export const useHotspotData = (selectedDate) => {
}
// 如果日期未变化且已有数据,跳过(除非是强制刷新)
if (lastDateRef.current === dateStr && !forceRefetch) {
if (lastDateRef.current === dateStr && data && !forceRefetch) {
return;
}
fetchingRef.current = true;
setLoading(true);
setError(null);
// 区分首次加载和后续刷新
if (!initializedRef.current) {
setLoading(true);
} else {
setRefreshing(true);
}
try {
const dateParam = selectedDate
? `?date=${dateStr}`
@@ -47,6 +58,7 @@ export const useHotspotData = (selectedDate) => {
if (result.success) {
setData(result.data);
lastDateRef.current = dateStr;
initializedRef.current = true;
} else {
setError(result.error || '获取数据失败');
}
@@ -55,16 +67,18 @@ export const useHotspotData = (selectedDate) => {
setError('网络请求失败');
} finally {
setLoading(false);
setRefreshing(false);
fetchingRef.current = false;
}
}, [selectedDate]); // 移除 data 依赖,避免循环更新
}, [selectedDate, data]);
useEffect(() => {
fetchData();
}, [fetchData]);
return {
loading,
loading, // 首次加载状态
refreshing, // 切换日期刷新状态
error,
data,
refetch: () => fetchData(true),