You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 02:20:25