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
相关产品推荐
相关产品推荐

