// src/views/Community/components/DynamicNewsCard/PaginationControl.js // 分页控制器组件 import React, { useState } from 'react'; import { Box, HStack, Button, Input, Text, IconButton, useColorModeValue, useToast, } from '@chakra-ui/react'; import { ChevronLeftIcon, ChevronRightIcon, } from '@chakra-ui/icons'; /** * 分页控制器组件(使用 React.memo 优化,避免不必要的重新渲染) * @param {number} currentPage - 当前页码 * @param {number} totalPages - 总页数 * @param {Function} onPageChange - 页码改变回调 */ const PaginationControl = React.memo(({ currentPage, totalPages, onPageChange }) => { const [jumpPage, setJumpPage] = useState(''); const toast = useToast(); const buttonBg = useColorModeValue('white', 'gray.700'); const activeBg = useColorModeValue('blue.500', 'blue.400'); const activeColor = useColorModeValue('white', 'white'); const borderColor = useColorModeValue('gray.300', 'gray.600'); const hoverBg = useColorModeValue('gray.100', 'gray.600'); // 生成页码数字列表(智能省略) const getPageNumbers = () => { const pageNumbers = []; const maxVisible = 5; // 最多显示5个页码(精简版) if (totalPages <= maxVisible) { // 总页数少,显示全部 for (let i = 1; i <= totalPages; i++) { pageNumbers.push(i); } } else { // 总页数多,使用省略号 if (currentPage <= 3) { // 当前页在前面 for (let i = 1; i <= 4; i++) { pageNumbers.push(i); } pageNumbers.push('...'); pageNumbers.push(totalPages); } else if (currentPage >= totalPages - 2) { // 当前页在后面 pageNumbers.push(1); pageNumbers.push('...'); for (let i = totalPages - 3; i <= totalPages; i++) { pageNumbers.push(i); } } else { // 当前页在中间 pageNumbers.push(1); pageNumbers.push('...'); pageNumbers.push(currentPage); pageNumbers.push('...'); pageNumbers.push(totalPages); } } return pageNumbers; }; // 处理页码跳转 const handleJump = () => { const page = parseInt(jumpPage, 10); if (isNaN(page)) { toast({ title: '请输入有效的页码', status: 'warning', duration: 2000, isClosable: true, }); return; } if (page < 1 || page > totalPages) { toast({ title: `页码范围:1 - ${totalPages}`, status: 'warning', duration: 2000, isClosable: true, }); return; } onPageChange(page); setJumpPage(''); }; // 处理回车键 const handleKeyPress = (e) => { if (e.key === 'Enter') { handleJump(); } }; const pageNumbers = getPageNumbers(); return ( {/* 上一页按钮 */} } size="xs" onClick={() => onPageChange(currentPage - 1)} isDisabled={currentPage === 1} bg={buttonBg} borderWidth="1px" borderColor={borderColor} _hover={{ bg: hoverBg }} aria-label="上一页" title="上一页" /> {/* 数字页码列表 */} {pageNumbers.map((page, index) => { if (page === '...') { return ( ... ); } return ( ); })} {/* 下一页按钮 */} } size="xs" onClick={() => onPageChange(currentPage + 1)} isDisabled={currentPage === totalPages} bg={buttonBg} borderWidth="1px" borderColor={borderColor} _hover={{ bg: hoverBg }} aria-label="下一页" title="下一页" /> {/* 分隔线 */} {/* 输入框跳转 */} 跳转到 setJumpPage(e.target.value)} onKeyPress={handleKeyPress} placeholder="页" bg={buttonBg} borderColor={borderColor} /> ); }, (prevProps, nextProps) => { // 自定义比较函数:只有当 currentPage 或 totalPages 变化时才重新渲染 return prevProps.currentPage === nextProps.currentPage && prevProps.totalPages === nextProps.totalPages; }); export default PaginationControl;