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:
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user