React实现高校周课程表渲染:API数据遍历问题求助
班级周课程表渲染实现方案
问题背景
开发高校教务处网站时,需将API返回的按天分组的课程数据,渲染为行对应课程节次、列对应星期的表格,单元格展示课程名、授课教师及教室信息。当前API返回数据格式为包含单键对象的数组(每个对象对应一天的课程列表),现有React代码无法正确嵌套遍历实现目标表格。
API返回数据结构示例:
[ { "Monday": [ { "id": 1, "subjectname": "Алгоритмы и вычислительные методы оптимизации", "formatsubject": "Практика", "teacher": "Куанышев В. Т.", "groupname": "ПЕ-12б", "numberpair": 1, "date_subject": "2024-04-22", "auditorium": "405 УК1" }, // ...更多课程项 { "auditorium": "", "date_subject": "", "numberpair": 7, "groupname": "", "teacher": "", "formatsubject": "", "subjectname": "", "id": "" } ] }, { "Tuesday": [...] }, // ...其余星期 ]
解决方案
步骤1:转换数据结构(可选,若无法调整API)
原数据格式为数组包裹的单日对象,先将其转换为{ 星期名: 课程数组 }的扁平对象,方便后续按节次匹配课程:
// 在组件中使用useMemo处理数据,避免重复计算 const formattedSchedule = useMemo(() => { const schedule = {}; data.forEach(dayObj => { const dayName = Object.keys(dayObj)[0]; schedule[dayName] = dayObj[dayName]; }); return schedule; }, [data]);
步骤2:确定课程节次范围
假设课程节次为1到7(可根据实际数据动态获取),定义节次数组:
const pairNumbers = Array.from({ length: 7 }, (_, i) => i + 1);
步骤3:渲染课程表表格
遍历节次数组生成每行,对每个节次,遍历所有星期,匹配对应节次的课程并渲染内容:
完整组件代码:
import axios from "axios"; import React, { useEffect, useState, useMemo } from 'react'; function Table() { const [data, setData] = useState([]); const pairNumbers = Array.from({ length: 7 }, (_, i) => i + 1); const weekDays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; useEffect(() => { axios.get('http://localhost:8080/getallshedule?date_start=2024-04-22&date_end=2024-04-27&groupname=ПЕ-12б') .then(res => setData(res.data)) .catch(er => console.log(er)); }, []); // 转换数据结构为{ 星期名: 课程数组 } const formattedSchedule = useMemo(() => { const schedule = {}; data.forEach(dayObj => { const dayName = Object.keys(dayObj)[0]; schedule[dayName] = dayObj[dayName]; }); return schedule; }, [data]); // 根据节次和星期获取对应课程 const getCourseByPairAndDay = (pair, day) => { const dayCourses = formattedSchedule[day] || []; return dayCourses.find(course => course.numberpair === pair); }; return ( <div> <table border="1" cellPadding="8"> <thead> <tr> <th>Pair</th> {weekDays.map(day => <th key={day}>{day}</th>)} </tr> </thead> <tbody> {pairNumbers.map(pair => ( <tr key={pair}> <td>{pair}</td> {weekDays.map(day => { const course = getCourseByPairAndDay(pair, day); return ( <td key={`${pair}-${day}`}> {course?.subjectname ? ( <div> <strong>{course.subjectname}</strong> <div>{course.teacher}</div> <div>{course.auditorium}</div> </div> ) : null} </td> ); })} </tr> ))} </tbody> </table> </div> ); } export default Table;
可选优化:调整API输出格式
如果可以修改API,建议直接返回扁平对象格式,无需数组包裹,减少前端数据处理步骤:
{ "Monday": [...], "Tuesday": [...], "Wednesday": [...], "Thursday": [...], "Friday": [...], "Saturday": [...] }
此时前端可直接使用formattedSchedule = data,省略数据转换逻辑。
内容的提问来源于stack exchange,提问作者Mikki158
相关产品推荐
相关产品推荐

