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

ReactJS提取嵌套数组数据渲染表格的问题与实现方案

现有代码的核心问题

你当前的实现有5个明确错误,导致无法渲染出预期效果:

  • 行结构逻辑错误:你在外层遍历每个请假原因组时,直接为每个组生成1个<tr>行标签,但预期效果是每个请假人对应1行,同个请假原因下的多个人需要生成多个独立行,把多个人的单元格塞到同一行里完全不符合表格结构规则。
  • JSX语法错误:内层的data.list.map是JS表达式,在JSX中必须包裹在{}中才能执行,你写的这部分代码不会被React解析,直接会报语法错误。
  • 缺少返回值:内层map的回调函数用{}包裹了逻辑,但没有显式return要渲染的<td>节点,这部分不会生成任何DOM内容。
  • 缺少必填key属性:React列表渲染时,循环生成的根节点必须设置唯一key值,否则会出现渲染性能下降、组件状态错乱的问题。
  • 表格结构缺失:没有编写<table>、<thead>、<tbody>等基础表格容器标签,零散的<tr>/<td>会被浏览器自动修正解析,导致结构完全混乱。
正确实现方案

双层遍历的思路本身是可行的,只需要调整遍历的层级逻辑:在外层遍历请假原因组时,不要直接生成行,而是在内层遍历组内的请假人时,为每个请假人生成独立的<tr>,同时携带当前组的reason字段即可。

写法1:先拍平数据再渲染(逻辑更清晰)

用flatMap把嵌套的接口数据提前转换成一维的行数据数组,每行对应一个请假人,之后直接遍历一维数组渲染即可,代码可读性更高:

import { FunctionComponent } from 'react';

// 接口返回的原始数据
const myArray = [
  {
    reason: 'vacation',
    list: [
      { name: 'John Doe', startsAt: '2022-05-19', endsAt: '2022-06-01' },
      { name: 'Jenifer Doe', startsAt: '2022-06-10', endsAt: '2022-06-15' }
    ],
  },
  {
    reason: 'sick',
    list: [{ name: 'Susan', startsAt: '2022-05-20', endsAt: '2022-05-21' }]
  }
];

export const MyComponent: FunctionComponent = () => {
  // 拍平为一维行数据:每条记录对应表格一行
  const tableRows = myArray.flatMap(group => 
    group.list.map(person => ({
      name: person.name,
      createdAt: person.startsAt,
      canceledAt: person.endsAt,
      reason: group.reason
    }))
  );

  return (
    <table>
      <thead>
        <tr>
          <th>Name</th>
          <th>Created at</th>
          <th>Canceled at</th>
          <th>Reason</th>
        </tr>
      </thead>
      <tbody>
        {tableRows.map((row, index) => (
          // 业务场景下如果有唯一用户id/请假单id,优先用id作为key
          <tr key={`${row.name}-${row.createdAt}-${index}`}>
            <td>{row.name}</td>
            <td>{row.createdAt}</td>
            <td>{row.canceledAt}</td>
            <td>{row.reason}</td>
          </tr>
        ))}
      </tbody>
    </table>
  );
};

写法2:JSX内直接嵌套遍历

如果不想提前处理数据,也可以直接在JSX结构中嵌套遍历,注意外层组需要用Fragment包裹多个<tr>,同时给Fragment设置key即可:

import { Fragment, FunctionComponent } from 'react';

const myArray = [/* 同上原始数据 */];

export const MyComponent: FunctionComponent = () => {
  return (
    <table>
      <thead>
        <tr>
          <th>Name</th>
          <th>Created at</th>
          <th>Canceled at</th>
          <th>Reason</th>
        </tr>
      </thead>
      <tbody>
        {myArray.map(group => (
          <Fragment key={group.reason}>
            {group.list.map(person => (
              <tr key={`${person.name}-${person.startsAt}`}>
                <td>{person.name}</td>
                <td>{person.startsAt}</td>
                <td>{person.endsAt}</td>
                <td>{group.reason}</td>
              </tr>
            ))}
          </Fragment>
        ))}
      </tbody>
    </table>
  );
};

两种写法最终渲染的表格结构完全匹配你给出的预期效果。

内容的提问来源于stack exchange,提问作者PandaMastr

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 18:27:39