You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React分页组件异常:切换页码时旧组件未移除,页码范围错误

问题分析与修复方案

你的分页组件出现两个核心问题,导致页码范围异常:

1. range函数逻辑错误

你实现的range函数第二个参数是数组长度,不是结束页码。比如当offset变为10时,range(offset - 5, offset)即range(5, 10)会生成10个元素(5到14),加上p+1后就变成6到15,这就是为什么会出现10个页码按钮的原因。

修正后的range函数应该根据起始和结束页码生成指定范围的数组:

function range(start, end) {
  // 生成从start到end(包含两端)的数组
  return Array.from({ length: end - start + 1 }, (_, index) => start + index);
}

2. Offset更新条件与页码生成逻辑不匹配

你用offset控制显示范围的逻辑存在偏差,初始offset=5对应显示1-5,但更新后offset=10时,你期望显示5-10,但实际生成的是6-15(因为range函数错误)。同时,触发offset更新的条件offset - curPage < 2逻辑不准确,会提前触发偏移量增加。

修正后的组件代码

调整offset的含义为当前显示的起始页码,并优化判断逻辑:

import { ChevronLeftIcon, ChevronRightIcon } from "@chakra-ui/icons";
import { Center, ButtonGroup, Button, IconButton } from "@chakra-ui/react";
import { useState } from "react";

function range(start, end) {
  return Array.from({ length: end - start + 1 }, (_, index) => start + index);
}

export default function Paginator({
  curPage,
  pageCnt,
  incPage,
  setPage,
  decPage,
}) {
  // 初始显示起始页码为1
  const [startPage, setStartPage] = useState(1);
  // 每页显示5个页码按钮
  const pageSize = 5;

  if (pageCnt < 2) return null;

  // 计算当前显示的结束页码,不超过总页数
  const endPage = Math.min(startPage + pageSize - 1, pageCnt);

  return (
    <Center mt="2">
      <ButtonGroup size="sm" variant="outline" isAttached>
        <IconButton
          icon={<ChevronLeftIcon boxSize={5} />}
          onClick={() => {
            decPage();
            // 当前页小于起始页码时,调整起始页码回退5
            if (curPage <= startPage - pageSize + 1) {
              setStartPage(prev => prev - pageSize);
            }
            window.scrollTo(0, 0);
          }}
          // 第一页时禁用左箭头
          isDisabled={curPage === 1}
        />
        {range(startPage, endPage).map((p) => (
          <Button
            key={p}
            // 当前页高亮
            colorScheme={curPage === p ? "blue" : undefined}
            onClick={() => {
              setPage(p);
              window.scrollTo(0, 0);
            }}
          >
            {p}
          </Button>
        ))}
        <IconButton
          icon={<ChevronRightIcon boxSize={5} />}
          onClick={() => {
            incPage();
            // 当前页等于结束页码时,调整起始页码前进5
            if (curPage >= endPage) {
              setStartPage(prev => prev + pageSize);
            }
            window.scrollTo(0, 0);
          }}
          // 最后一页时禁用右箭头
          isDisabled={curPage === pageCnt}
        />
      </ButtonGroup>
    </Center>
  );
}

关键优化点

  • 将offset改为startPage,直接表示当前显示的起始页码,逻辑更清晰
  • 计算endPage时限制不超过总页数,避免显示不存在的页码
  • 左/右箭头点击时,根据当前页与显示范围的关系调整startPage
  • 增加箭头按钮的禁用状态,提升交互体验
  • 高亮当前页码,增强视觉反馈

内容的提问来源于stack exchange,提问作者Amol Borkar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 22:15:02