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

React分页组件每页结果更新仅第一页生效及pageCount错误排查

React分页问题修复方案

核心问题分析

  1. pageCount非整数错误:必须用Math.ceil(总数据量 / 每页数量)计算总页数,且计算逻辑要和每页数量、总数据量绑定,每次这两个值变化时重新计算。
  2. 切换每页数量后分页异常:修改每页数量时未重置当前页到第一页,导致当前页超出新的总页数范围,剩余数据被错误截取。

修复代码示例

以下是完整的函数组件修复实现,包含关键逻辑:

import { useState, useMemo } from 'react';

function ProductPagination({ products }) {
  const [currentPage, setCurrentPage] = useState(1);
  const [perPage, setPerPage] = useState(10);

  // 用useMemo缓存总页数,确保数据或每页数量变化时自动更新
  const pageCount = useMemo(() => {
    // 重点:Math.ceil强制总页数为整数,解决非整数错误
    return Math.ceil(products.length / perPage);
  }, [products.length, perPage]);

  // 切换每页数量时必须重置到第一页
  const handlePerPageChange = (newPerPage) => {
    setPerPage(newPerPage);
    setCurrentPage(1); // 这步是解决分页异常的核心
  };

  // 计算当前页显示的商品数据
  const currentProducts = useMemo(() => {
    const startIdx = (currentPage - 1) * perPage;
    const endIdx = startIdx + perPage;
    return products.slice(startIdx, endIdx);
  }, [products, currentPage, perPage]);

  return (
    <div>
      {/* 每页数量选择器 */}
      <select 
        value={perPage} 
        onChange={(e) => handlePerPageChange(Number(e.target.value))}
      >
        <option value={5}>5条/页</option>
        <option value={10}>10条/页</option>
        <option value={20}>20条/页</option>
      </select>

      {/* 商品列表 */}
      <ul>
        {currentProducts.map(product => (
          <li key={product.id}>{product.name}</li>
        ))}
      </ul>

      {/* 分页控件 */}
      <div className="pagination">
        <button 
          onClick={() => setCurrentPage(prev => Math.max(prev - 1, 1))} 
          disabled={currentPage === 1}
        >
          上一页
        </button>
        {Array.from({ length: pageCount }, (_, i) => i + 1).map(page => (
          <button
            key={page}
            onClick={() => setCurrentPage(page)}
            style={{ 
              backgroundColor: currentPage === page ? '#007bff' : 'transparent',
              color: currentPage === page ? 'white' : 'inherit',
              border: '1px solid #007bff',
              padding: '4px 8px',
              margin: '0 2px'
            }}
          >
            {page}
          </button>
        ))}
        <button 
          onClick={() => setCurrentPage(prev => Math.min(prev + 1, pageCount))} 
          disabled={currentPage === pageCount}
        >
          下一页
        </button>
      </div>
    </div>
  );
}

关键修复点说明

  1. pageCount的正确计算:

    • 用useMemo缓存计算结果,避免重复渲染,依赖products.length和perPage,确保这两个值变化时自动更新总页数。
    • 强制用Math.ceil取上取整,比如总数据25条、每页10条,总页数是3而非2.5,彻底解决非整数错误。
  2. 切换每页数量时重置当前页:

    • 修改perPage后立即把currentPage设为1,避免出现当前页大于新总页数的情况(比如原来在第3页,切换每页数量为20后,新总页数是2,第3页不存在,导致slice截取到末尾,看起来剩余数据全在第二页)。
  3. 数据截取逻辑:

    • 用(currentPage - 1) * perPage计算起始索引,确保每页数据的起始位置正确,不管perPage怎么变化都能准确截取。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 04:35:32