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

React嵌套数组分页实现:遍历嵌套数组并每页返回20个元素

问题:嵌套数组分页实现(保留原结构)

我有一个包含多个子数组的嵌套数组:

export const ArtifactArray = [
  AccessoriesArtifacts,
  BodyArtifacts,
  CloakArtifacts,
  FeetArtifacts,
  HandsArtifacts,
  HeadArtifacts,
  LeftHandArtifacts,
  MainHandArtifacts,
  NeckArtifacts
]

每个子数组包含具体的对象:

export const BodyArtifacts = [
  WonderArmor,
  BrimstoneBreastplate,
  PetrifiedWoodBreastplate,
  DragonScaleArmor,
  RibCage,
  GreatBasilistScales,
  TitansCuirass,
  CyclopsKingTunic,
];

目前我通过嵌套map遍历渲染所有元素:

{ArtifactArray.map((array, index) => (
  <Fragment key={index}>
    {array.map((artifact, index) => (
      <ArtifactsBlock
        key={index}
        src={artifact.pic}
        name={artifact.name}
      />
    ))}
  </Fragment>
))}

现在需要添加分页功能,每页显示20个对象(总计120个)。但直接对子数组使用slice会因为子数组长度不一致导致分页元素数量不符,且我不想将所有子数组合并为一维数组,希望保留现有嵌套结构,请问该如何实现?


解决方案

核心思路是跟踪全局元素的起始/结束位置,对每个子数组计算需要截取的片段,最终返回和原结构一致的嵌套数组,仅包含当前页的元素。

步骤1:实现分页数据处理函数

编写一个函数,根据当前页码计算出需要从每个子数组中截取的元素范围:

// 每页展示数量
const PAGE_SIZE = 20;
// 总元素数,也可以通过遍历ArtifactArray动态计算
const TOTAL_ITEMS = 120;

// 获取分页后的嵌套数组
const getPaginatedArtifacts = (pageNumber) => {
  const start = (pageNumber - 1) * PAGE_SIZE;
  let end = start + PAGE_SIZE;
  const paginated = [];
  let currentTotal = 0;

  for (const subArray of ArtifactArray) {
    const subLength = subArray.length;
    // 计算当前子数组需要截取的起始和结束索引
    const subStart = Math.max(0, start - currentTotal);
    const subEnd = Math.min(subLength, end - currentTotal);

    // 按范围截取元素,无元素则保留空数组
    paginated.push(subArray.slice(subStart, subEnd));

    currentTotal += subLength;
    // 已取够当前页元素时,提前终止循环并补全剩余空数组
    if (currentTotal >= end) {
      while (paginated.length < ArtifactArray.length) {
        paginated.push([]);
      }
      break;
    }
  }

  return paginated;
};

步骤2:在组件中使用分页数据

在组件中维护当前页码状态,调用上述函数获取分页数据后渲染:

import { useState, Fragment } from 'react';

const ArtifactsPage = () => {
  const [currentPage, setCurrentPage] = useState(1);
  const paginatedArtifacts = getPaginatedArtifacts(currentPage);
  const totalPages = Math.ceil(TOTAL_ITEMS / PAGE_SIZE);

  return (
    <>
      {/* 分页控制栏 */}
      <div className="pagination-bar">
        <button 
          onClick={() => setCurrentPage(prev => Math.max(1, prev - 1))}
          disabled={currentPage === 1}
        >
          上一页
        </button>
        <span>第 {currentPage} 页 / 共 {totalPages} 页</span>
        <button 
          onClick={() => setCurrentPage(prev => Math.min(totalPages, prev + 1))}
          disabled={currentPage === totalPages}
        >
          下一页
        </button>
      </div>

      {/* 渲染分页后的元素 */}
      {paginatedArtifacts.map((array, index) => (
        <Fragment key={index}>
          {array.map((artifact, artifactIndex) => (
            <ArtifactsBlock
              key={artifactIndex}
              src={artifact.pic}
              name={artifact.name}
            />
          ))}
        </Fragment>
      ))}
    </>
  );
};

补充说明

  • 该方案完全保留原嵌套数组的结构,每个子数组对应原数组的位置,仅包含当前页需要展示的元素(无元素时为空数组)。
  • 若不想渲染空数组对应的结构,可以在渲染时过滤空数组:paginatedArtifacts.filter(arr => arr.length > 0).map(...)。
  • 总元素数TOTAL_ITEMS也可以通过动态计算得到:const TOTAL_ITEMS = ArtifactArray.reduce((sum, arr) => sum + arr.length, 0),避免硬编码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 10:47:40