src/views/Community/
├── index.js (主组件,150行左右)
├── components/
│ ├── EventTimelineCard.js (新增)
│ ├── EventTimelineHeader.js (新增)
│ ├── EventListSection.js (新增)
│ ├── HotEventsSection.js (新增)
│ ├── EventModals.js (新增)
│ ├── UnifiedSearchBox.js (已有)
│ ├── EventList.js (已有)
│ └── ...
└── hooks/
├── useEventFilters.js (新增)
└── useEventData.js (新增)
92 lines
2.6 KiB
JavaScript
92 lines
2.6 KiB
JavaScript
// src/views/Community/hooks/useEventData.js
|
||
// 事件数据加载逻辑 Hook
|
||
|
||
import { useState, useEffect, useRef, useCallback } from 'react';
|
||
import { debounce } from 'lodash';
|
||
import { eventService } from '../../../services/eventService';
|
||
import { logger } from '../../../utils/logger';
|
||
|
||
/**
|
||
* 事件数据加载 Hook
|
||
* @param {Object} filters - 筛选条件
|
||
* @param {number} pageSize - 每页数量
|
||
* @returns {Object} 事件数据和加载状态
|
||
*/
|
||
export const useEventData = (filters, pageSize = 10) => {
|
||
const [events, setEvents] = useState([]);
|
||
const [pagination, setPagination] = useState({
|
||
current: 1,
|
||
pageSize: pageSize,
|
||
total: 0
|
||
});
|
||
const [loading, setLoading] = useState(false);
|
||
const [lastUpdateTime, setLastUpdateTime] = useState(new Date());
|
||
|
||
// 加载事件列表
|
||
const loadEvents = useCallback(async (page = 1) => {
|
||
logger.debug('useEventData', 'loadEvents 被调用', { page });
|
||
setLoading(true);
|
||
|
||
try {
|
||
const response = await eventService.getEvents({
|
||
...filters,
|
||
page,
|
||
per_page: pagination.pageSize
|
||
});
|
||
|
||
if (response.success) {
|
||
setEvents(response.data.events);
|
||
setPagination({
|
||
current: response.data.pagination.page,
|
||
pageSize: response.data.pagination.per_page,
|
||
total: response.data.pagination.total
|
||
});
|
||
setLastUpdateTime(new Date());
|
||
|
||
logger.debug('useEventData', 'loadEvents 成功', {
|
||
count: response.data.events.length,
|
||
total: response.data.pagination.total
|
||
});
|
||
}
|
||
} catch (error) {
|
||
logger.error('useEventData', 'loadEvents', error, {
|
||
page,
|
||
filters
|
||
});
|
||
} finally {
|
||
setLoading(false);
|
||
}
|
||
}, [filters, pagination.pageSize]);
|
||
|
||
// 创建防抖的 loadEvents 函数(500ms 防抖延迟)
|
||
const debouncedLoadEvents = useRef(
|
||
debounce((page) => {
|
||
logger.debug('useEventData', '防抖后执行 loadEvents', { page });
|
||
loadEvents(page);
|
||
}, 500)
|
||
).current;
|
||
|
||
// 监听 filters 变化,自动加载数据
|
||
// 防抖优化:用户快速切换筛选条件时,只执行最后一次请求
|
||
useEffect(() => {
|
||
logger.debug('useEventData', 'useEffect 触发,filters 变化', { filters });
|
||
|
||
// 使用防抖加载事件
|
||
debouncedLoadEvents(filters.page || 1);
|
||
|
||
// 组件卸载时取消防抖
|
||
return () => {
|
||
debouncedLoadEvents.cancel();
|
||
};
|
||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||
}, [filters]); // 监听 filters 状态变化
|
||
|
||
return {
|
||
events,
|
||
pagination,
|
||
loading,
|
||
lastUpdateTime,
|
||
loadEvents
|
||
};
|
||
};
|