如何在React组件中基于给定API数据使用嵌套Map渲染课程主题层级
问题原因
你代码的语法错误和逻辑问题主要有以下几点:
- map回调函数参数写法错误,
LessonList.map(() => (lesson)、lesson.topics.map(() => (t)完全不符合JS箭头函数的写法规范,遍历元素应该作为回调函数的入参 - 同级返回多个JSX节点没有用Fragment包裹,会触发JSX语法错误
- 主题项的key和显示内容写死为固定值,没有使用遍历得到的主题变量,且key必须全局唯一
- 你的需求是按「主题-对应课程」的层级展示,原代码是按「课程-对应主题」的逻辑写的,和需求不符,需要先对接口返回的数据做分组转换
修复步骤
第一步:数据分组转换
先把接口返回的课程带主题的结构,转换为主题带关联课程的结构:
// 对原数据做按主题分组处理 const groupByTopic = () => { const topicMap = {} LessonList.forEach(lesson => { lesson.topics.forEach(topic => { if(!topicMap[topic]) { topicMap[topic] = [] } topicMap[topic].push(lesson.title) }) }) return topicMap } const topicGroups = groupByTopic()
第二步:修复渲染代码
<List> {Object.entries(topicGroups).map(([topic, lessons]) => ( <React.Fragment key={topic}> {/* 主题层级 */} <ListItem button className={classes.LessonTopics}> <ListItemIcon><FiberManualRecordIcon /></ListItemIcon> <ListItemText primary={topic} /> </ListItem> {/* 对应课程层级 */} {lessons.map(lesson => ( <ListItem button className={classes.LessonTitle} key={lesson}> <ListItemIcon><FiberManualRecordOutlinedIcon /></ListItemIcon> <ListItemText primary={lesson} /> </ListItem> ))} </React.Fragment> ))} </List>
如果你还是需要原来的「课程-对应主题」的展示结构,用下面的修复后代码即可:
<List> {LessonList.map((lesson) => ( <React.Fragment key={lesson.title}> <ListItem button className={classes.LessonTitle}> <ListItemIcon><FiberManualRecordOutlinedIcon /></ListItemIcon> <ListItemText primary={lesson.title} /> </ListItem> {lesson.topics.map((t) => ( <ListItem button className={classes.LessonTopics} key={t}> <ListItemIcon><FiberManualRecordIcon /></ListItemIcon> <ListItemText primary={t} /> </ListItem> ))} </React.Fragment> ))} </List>
内容的提问来源于stack exchange,提问作者Waqas Devolper
相关产品推荐
相关产品推荐

