提问人:Pav 提问时间:5/9/2023 最后编辑:Pav 更新时间:5/9/2023 访问量:59
如何遍历数组并使其仅返回少数元素,具体取决于 React 状态
How to iterate through an array of arrays and make it return only a handful of elements depending on React state
问:
我有一个包含其他数组的数组:
export const ArtifactArray = [
AccessoriesArtifacts,
BodyArtifacts,
CloakArtifacts,
FeetArtifacts,
HandsArtifacts,
HeadArtifacts,
LeftHandArtifacts,
MainHandArtifacts,
NeckArtifacts
]
这些数组中的每一个都包含对象:
export const BodyArtifacts = [
WonderArmor,
BrimstoneBreastplate,
PetrifiedWoodBreastplate,
DragonScaleArmor,
RibCage,
GreatBasilistScales,
TitansCuirass,
CyclopsKingTunic,
];
稍后,我将遍历数组,并在屏幕上显示所有这些对象,如下所示:
{ArtifactArray.map((array, index) => (
<Fragment key={index}>
{array.map((artifact, index) => (
<ArtifactsBlock
key={index}
src={artifact.pic}
name={artifact.name}
/>
))}
</Fragment>
))}
一切都按预期进行。
然后我尝试向它添加分页,这就是问题开始的地方。我只想每页返回 20 个对象(总共 120 个)。但是,如果这些数组中每个数组中没有相同数量的对象,我该怎么办?如果我使用array.slice(0, 20),array.slice(20, 40)等,在其中一些数组的末尾,它将返回11或9。当然,我可以摆脱那些内部数组,简单地将所有对象集中到一个数组中,但这太笨拙了。我想保持现在的样子。
答:
1赞
bebbi
5/9/2023
#1
把你的清单扁平化怎么样?
{ArtifactArray.flat().slice(i, i + pageLen).map(artifact, index) => (
<ArtifactsBlock
key={index}
src={artifact.pic}
name={artifact.name}
/>
)}
0赞
Andy
5/9/2023
#2
您可以将对象数组扁平化为一个数组,然后使用该数组的长度加上要显示的项目数的“限制”来确定如何对数据进行切片。
这是一个使用小型数据集(总共 11 个项目)的小工作示例。数据被展平并传递到组件中。有两种状态:一种用于页面,一种用于限制。注意:此处的限制设置为每页两个项目。
当呈现组件时,它会同时调用 和 函数。它们使用页面和限制状态中的信息构建一系列页面按钮和一系列工件。getPages
getArtifacts
const { useState } = React;
function Example({ artifacts }) {
const [ page, setPage ] = useState(0);
const [ limit, setLimit ] = useState(2);
// Return a subset of data from the artifacts state based
// on the page number, and the page limit
function getArtifacts() {
return artifacts
.slice(page * limit, (page * limit) + limit)
.map(artifact => {
return (
<Artifact
key={artifact.id}
data={artifact}
/>
);
});
}
// Update the page state
function handlePage(e) {
const { dataset: { page } } = e.target;
setPage(+page);
}
// Create a series of pages based on the number of objects
// in the artifacts state, and the page limit. Add an active prop
// to indicate which page button should be highlighted
function getPages() {
const arr = [];
const mod = artifacts.length / limit;
const pages = mod % limit === 0 ? mod : Math.floor(mod) + 1;
for (let p = 0; p < pages; p++) {
arr.push((
<Page
key={p}
number={p}
active={p === page}
handlePage={handlePage}
/>)
);
}
return arr;
}
// Get the pages and the artifacts
return (
<main>
<h2>Artifacts</h2>
<section className="pages">
{getPages()}
</section>
<section className="artifacts">
{getArtifacts()}
</section>
</main>
);
}
// Return an artifact name
function Artifact({ data }) {
return <section><h4>{data.name}</h4></section>;
}
// Return a page
function Page({ number, active, handlePage }) {
const cn = ['page', active && 'active'].join(' ');
return (
<button
className={cn}
data-page={number}
type="button"
onClick={handlePage}
>{number + 1}
</button>
);
}
const bodyArtifacts=[{id:"ba1",name:"WonderArmor"},{id:"ba2",name:"BrimstoneBreastplate"},{id:"ba3",name:"PetrifiedWoodBreastplate"},{id:"ba4",name:"DragonScaleArmor"},{id:"ba5",name:"GreatBasilistScales"},{id:"ba6",name:"TitansCuirass"},{id:"ba7",name:"CyclopsKingTunic"}];
const cloakArtifacts=[{id:"ca1",name:"RedCloak"},{id:"ca2",name:"BlueCloak"},{id:"ca3",name:"PinkCloak"},{id:"ca4",name:"GoldCloak"}];
const artifacts=[bodyArtifacts,cloakArtifacts];
const node = document.getElementById('root');
const root = ReactDOM.createRoot(node);
// Pass in the flattened data
root.render(<Example artifacts={artifacts.flat()} />);
.page { width: 30px; aspect-ratio: 1; border-radius: 5px;}
.page:not(:last-child) { margin-right: 0.25rem; }
.page:hover:not(.active) { background-color: #fffff0; cursor: pointer; }
.active { background-color: lightgreen; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.development.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.development.min.js"></script>
<div id="root"></div>
评论