本文讲解如何在 react 中安全、高效地遍历和渲染嵌套结构的 api 数据(如多层关联的卡片与子标题),重点解决双重 map 带来的可维护性与潜在性能隐患,并强调 key 的必要性、空值防护及结构化预处理技巧。
在 React 应用中,渲染嵌套数据(例如「卡片 → 子标题列表」)时,直接在 JSX 中嵌套 map 虽然直观,但存在三类关键问题:缺少唯一 key 导致重渲染异常、未处理空值引发运行时错误、深层嵌套降低可读性与扩展性。尤其当 cardItems 规模增长或 card_sub_headings.data 为空/undefined 时,原始代码会抛出 TypeError: Cannot read property 'map' of undefined。
✅ 正确做法不是「避免双重 map」本身(因为 DOM 结构天然需要两层遍历),而是确保每一层遍历都健壮、可追踪、可优化:
必设唯一 key:React 依赖 key 识别元素身份。ele.attributes.id 和 x.attributes.id 是理想选择(需后端保证其唯一性与非空);若无 ID,可用 ele.id 或 index(仅限静态、不可增删的列表,不推荐)。
空值防御前置:使用可选链(?.)+ 空值合并(?? [])替代裸 map:
{ele.attributes?.card_sub_headings?.data?.map((x) => (
{x.attributes?.title || '—'}
))}结构预处理(推荐进阶方案):在数据获取阶段就扁平化/标准化,提升 JSX 可读性与复用性:
// 在 getCardsData 中预处理
const normalizedCards = json?.data.map((card) => ({
id: card.id,
heading: card.attributes.heading,
subHeadings: card.attributes.card_sub_headings?.da
ta
?.filter(Boolean)
.map((sub) => ({
id: sub.id,
title: sub.attributes?.title || ''
})) || []
}));
setCardItems(normalizedCards);随后 JSX 可简化为:
cardItems.map((card) => ({card.heading}
{card.subHeadings.map((sub) => ({sub.title}
))} ));
⚠️ 注意事项:
总结:优化核心在于数据可靠性 + 渲染确定性,而非单纯减少 map 层级。加上 key、防御空值、提前归一化结构,即可兼顾性能、可维护性与扩展性。