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