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

React分类切换分页异常:分页消失且无法统计分类总页数

React分类分页异常修复方案

问题现象

点击分类按钮后分页组件消失,且无法正确统计当前分类下的总页数。


前端修复步骤

1. 修正分页计数的响应式逻辑

原代码中count变量的赋值未跟随分类状态实时更新,需将其改为响应式判断:

// 替换原count变量定义,放在组件内部(useState之后)
const count = category ? filteredContentCount : contentsCount;

2. 修复分页组件的总项数参数

分页组件的totalItemsCount需使用当前分类对应的总条数,而非全量内容总数:

{(resPerPage <= count) && (
  <div className="d-flex justify-content-center mt-5">
    <Pagination
      activePage={currentPage}
      itemsCountPerPage={resPerPage}
      totalItemsCount={count} // 替换为count,匹配当前分类总条数
      onChange={setCurrentPageNo}
      nextPageText={'Next'}
      prevPageText={'Prev'}
      firstPageText={'First'}
      lastPageText={'Last'}
      itemClass="page-item"
      linkClass="page-link"
    />
  </div>
)}

3. 分类切换时重置页码

切换分类后重置页码为第一页,避免出现空数据页:

function setCategories(category) {
  setCurrentPage(1); // 新增页码重置逻辑
  setCategory(category);
}

后端修复步骤

1. 正确计算分类下的总条数

原代码中filteredContentCount取的是分页后的数据长度,并非分类下的总条数。需在分页前单独查询分类过滤后的总数量:

exports.getContents = asyncErrors(async (req, res, next) => {
  const resPerPage = 9;

  // 构建完整过滤条件(复用APIFeatures的过滤逻辑)
  let filterQuery = {};
  // 处理搜索关键词
  if (req.query.keyword) {
    filterQuery.name = { $regex: req.query.keyword, $options: 'i' };
  }
  // 处理其他过滤参数
  const queryCopy = { ...req.query };
  const removeFields = ['keyword', 'limit', 'page'];
  removeFields.forEach(el => delete queryCopy[el]);
  let queryStr = JSON.stringify(queryCopy);
  queryStr = queryStr.replace(/\b(gt|gte|lt|lte)\b/g, match => `$${match}`);
  Object.assign(filterQuery, JSON.parse(queryStr));

  // 计算全量总数和分类过滤后的总数
  const contentsCount = await Content.countDocuments();
  const filteredContentCount = await Content.countDocuments(filterQuery);

  // 执行分页查询
  const apiFeatures = new APIFeatures(Content.find(filterQuery), req.query)
    .pagination(resPerPage);

  const contents = await apiFeatures.query;

  res.status(200).json({
    success: true,
    contents,
    contentsCount,
    resPerPage,
    filteredContentCount
  });
});

2. 优化APIFeatures类(可选)

抽离过滤逻辑,避免后端代码重复:

class APIFeatures {
  constructor(query, queryStr) {
    this.query = query;
    this.queryStr = queryStr;
    this.filterQuery = {}; // 存储过滤条件
  }

  search() {
    const keyword = this.queryStr.keyword ? {
      name: { $regex: this.queryStr.keyword, $options: 'i' }
    } : {};
    Object.assign(this.filterQuery, keyword);
    this.query = this.query.find(this.filterQuery);
    return this;
  }

  filter() {
    const queryCopy = { ...this.queryStr };
    const removeFields = ['keyword', 'limit', 'page'];
    removeFields.forEach(el => delete queryCopy[el]);

    let queryStr = JSON.stringify(queryCopy);
    queryStr = queryStr.replace(/\b(gt|gte|lt|lte)\b/g, match => `$${match}`);
    Object.assign(this.filterQuery, JSON.parse(queryStr));

    this.query = this.query.find(this.filterQuery);
    return this;
  }

  pagination(resPerPage) {
    const currentPage = Number(this.queryStr.page) || 1;
    const skip = resPerPage * (currentPage - 1);
    this.query = this.query.limit(resPerPage).skip(skip);
    return this;
  }

  // 获取最终过滤条件
  getFilterQuery() {
    return this.filterQuery;
  }
}

module.exports = APIFeatures;

优化后后端调用方式:

const apiFeatures = new APIFeatures(Content.find(), req.query).search().filter();
const filteredContentCount = await Content.countDocuments(apiFeatures.getFilterQuery());
apiFeatures.pagination(resPerPage);
const contents = await apiFeatures.query;

验证要点

  1. 点击分类按钮,页码自动重置为1,分页组件显示当前分类的总页数
  2. 切换分类时,分页组件正常显示,页数计算准确
  3. 分页切换时,加载对应分类的对应页数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 16:45:45