feat: 提取 usePagination Hook
This commit is contained in:
@@ -26,52 +26,20 @@ import UnifiedSearchBox from './UnifiedSearchBox';
|
||||
import { fetchDynamicNews, toggleEventFollow, selectEventFollowStatus } from '../../../store/slices/communityDataSlice';
|
||||
|
||||
/**
|
||||
* 实时要闻·动态追踪 - 事件展示卡片组件
|
||||
* @param {Array} allCachedEvents - 完整缓存事件列表(从 Redux 传入)
|
||||
* @param {boolean} loading - 加载状态
|
||||
* @param {number} total - 服务端总数量
|
||||
* @param {number} cachedCount - 已缓存数量
|
||||
* @param {Object} filters - 筛选条件
|
||||
* @param {Array} popularKeywords - 热门关键词
|
||||
* @param {Date} lastUpdateTime - 最后更新时间
|
||||
* @param {Function} onSearch - 搜索回调
|
||||
* @param {Function} onSearchFocus - 搜索框获得焦点回调
|
||||
* @param {Function} onEventClick - 事件点击回调
|
||||
* @param {Function} onViewDetail - 查看详情回调
|
||||
* @param {Object} ref - 用于滚动的ref
|
||||
* 分页逻辑自定义 Hook
|
||||
* @param {Object} options - Hook 配置选项
|
||||
* @param {Array} options.allCachedEvents - 完整缓存事件列表
|
||||
* @param {number} options.total - 服务端总数量
|
||||
* @param {number} options.cachedCount - 已缓存数量
|
||||
* @param {Function} options.dispatch - Redux dispatch 函数
|
||||
* @param {Function} options.toast - Toast 通知函数
|
||||
* @returns {Object} 分页状态和方法
|
||||
*/
|
||||
const DynamicNewsCard = forwardRef(({
|
||||
allCachedEvents = [],
|
||||
loading,
|
||||
total = 0,
|
||||
cachedCount = 0,
|
||||
filters = {},
|
||||
popularKeywords = [],
|
||||
lastUpdateTime,
|
||||
onSearch,
|
||||
onSearchFocus,
|
||||
onEventClick,
|
||||
onViewDetail,
|
||||
...rest
|
||||
}, ref) => {
|
||||
const dispatch = useDispatch();
|
||||
const toast = useToast();
|
||||
const cardBg = useColorModeValue('white', 'gray.800');
|
||||
const borderColor = useColorModeValue('gray.200', 'gray.700');
|
||||
|
||||
// 从 Redux 读取关注状态
|
||||
const eventFollowStatus = useSelector(selectEventFollowStatus);
|
||||
|
||||
// 关注按钮点击处理
|
||||
const handleToggleFollow = useCallback((eventId) => {
|
||||
dispatch(toggleEventFollow(eventId));
|
||||
}, [dispatch]);
|
||||
|
||||
const usePagination = ({ allCachedEvents, total, cachedCount, dispatch, toast }) => {
|
||||
// 本地状态
|
||||
const [selectedEvent, setSelectedEvent] = useState(null);
|
||||
const [mode, setMode] = useState('carousel'); // 'carousel' 或 'grid',默认单排
|
||||
const [currentPage, setCurrentPage] = useState(1); // 当前页码
|
||||
const [loadingPage, setLoadingPage] = useState(null); // 正在加载的目标页码(用于 UX 提示)
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [loadingPage, setLoadingPage] = useState(null);
|
||||
const [mode, setMode] = useState('carousel'); // 'carousel' 或 'grid'
|
||||
|
||||
// 根据模式决定每页显示数量
|
||||
const pageSize = mode === 'carousel' ? 5 : 10;
|
||||
@@ -335,6 +303,86 @@ const DynamicNewsCard = forwardRef(({
|
||||
// 如果第1页数据完整,不发起请求,直接切换
|
||||
}, [mode, allCachedEvents, total, dispatch]);
|
||||
|
||||
return {
|
||||
// 状态
|
||||
currentPage,
|
||||
mode,
|
||||
loadingPage,
|
||||
pageSize,
|
||||
totalPages,
|
||||
hasMore,
|
||||
currentPageEvents,
|
||||
|
||||
// 方法
|
||||
handlePageChange,
|
||||
handleModeToggle
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* 实时要闻·动态追踪 - 事件展示卡片组件
|
||||
* @param {Array} allCachedEvents - 完整缓存事件列表(从 Redux 传入)
|
||||
* @param {boolean} loading - 加载状态
|
||||
* @param {number} total - 服务端总数量
|
||||
* @param {number} cachedCount - 已缓存数量
|
||||
* @param {Object} filters - 筛选条件
|
||||
* @param {Array} popularKeywords - 热门关键词
|
||||
* @param {Date} lastUpdateTime - 最后更新时间
|
||||
* @param {Function} onSearch - 搜索回调
|
||||
* @param {Function} onSearchFocus - 搜索框获得焦点回调
|
||||
* @param {Function} onEventClick - 事件点击回调
|
||||
* @param {Function} onViewDetail - 查看详情回调
|
||||
* @param {Object} ref - 用于滚动的ref
|
||||
*/
|
||||
const DynamicNewsCard = forwardRef(({
|
||||
allCachedEvents = [],
|
||||
loading,
|
||||
total = 0,
|
||||
cachedCount = 0,
|
||||
filters = {},
|
||||
popularKeywords = [],
|
||||
lastUpdateTime,
|
||||
onSearch,
|
||||
onSearchFocus,
|
||||
onEventClick,
|
||||
onViewDetail,
|
||||
...rest
|
||||
}, ref) => {
|
||||
const dispatch = useDispatch();
|
||||
const toast = useToast();
|
||||
const cardBg = useColorModeValue('white', 'gray.800');
|
||||
const borderColor = useColorModeValue('gray.200', 'gray.700');
|
||||
|
||||
// 从 Redux 读取关注状态
|
||||
const eventFollowStatus = useSelector(selectEventFollowStatus);
|
||||
|
||||
// 关注按钮点击处理
|
||||
const handleToggleFollow = useCallback((eventId) => {
|
||||
dispatch(toggleEventFollow(eventId));
|
||||
}, [dispatch]);
|
||||
|
||||
// 本地状态
|
||||
const [selectedEvent, setSelectedEvent] = useState(null);
|
||||
|
||||
// 使用分页 Hook
|
||||
const {
|
||||
currentPage,
|
||||
mode,
|
||||
loadingPage,
|
||||
pageSize,
|
||||
totalPages,
|
||||
hasMore,
|
||||
currentPageEvents,
|
||||
handlePageChange,
|
||||
handleModeToggle
|
||||
} = usePagination({
|
||||
allCachedEvents,
|
||||
total,
|
||||
cachedCount,
|
||||
dispatch,
|
||||
toast
|
||||
});
|
||||
|
||||
// 初始加载
|
||||
useEffect(() => {
|
||||
if (allCachedEvents.length === 0) {
|
||||
|
||||
Reference in New Issue
Block a user