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

React JS中循环遍历数组渲染表格时触发控制台报错

问题背景

需要遍历App.js中的expenses数组,以表格形式在浏览器中输出数组内容。
待遍历数组截图

已编写代码

App.js return 片段

return (
    
    <div className="container">
      <h1> Expenses </h1>

      <table className="table table-bordered">
        <tr>
          <th>Title</th>
          <th>Amount</th>
          <th>Date</th>
        </tr>

        {expenses.map((expense, index) => (
          <tr data-index={index}>
            <td>{expense.title}</td>
            <td>{expense.amount}</td>
            <td>{expense.date}</td>
          </tr>
        ))}

      </table>

    </div>
  );

ExpenseItem 组件代码

import './ExpenseItem.css';

function ExpenseItem(props) {
    return (
        <div className="expense-item" >
            <div>{props.date.toISOString()}</div>
            <div className="expense-item__description">
                <h2>{props.title}</h2>
                <div className="expense-item__price">{props.amount}</div>
            </div>
        </div>
    )
}

export default ExpenseItem

代码运行后控制台抛出报错:
控制台报错截图

报错原因
  • 列表渲染未加唯一key属性:React对map生成的同级列表元素要求必须传入唯一key值用于虚拟DOM对比,缺失会直接抛出警告,特殊场景下会导致渲染错位。
  • 日期类型兼容缺失:如果expenses数组内的date字段是字符串而非Date实例,直接调用toISOString()方法会触发「xxx.toISOString is not a function」的类型错误;如果date是Date实例,直接在td标签中渲染会输出完整的时间对象转字符串结果,格式冗余不符合展示需求。
  • 代码冗余且结构不符合规范:已编写的ExpenseItem组件未在表格渲染逻辑中使用,且组件根元素为div,无法直接作为表格行嵌入table结构,会导致HTML解析异常。
修复方案

方案1:直接修正表格渲染逻辑(不使用ExpenseItem组件)

补全table标签的thead、tbody语义化结构,给列表行加key,统一日期格式化逻辑:

return (
  <div className="container">
    <h1>Expenses</h1>
    <table className="table table-bordered">
      <thead>
        <tr>
          <th>Title</th>
          <th>Amount</th>
          <th>Date</th>
        </tr>
      </thead>
      <tbody>
        {expenses.map((expense, index) => {
          // 兼容字符串/Date对象两种日期格式
          const date = expense.date instanceof Date ? expense.date : new Date(expense.date);
          return (
            // 优先用数据自带的唯一id作为key,无id时用index兜底
            <tr key={expense.id ?? index}>
              <td>{expense.title}</td>
              <td>{expense.amount}</td>
              <td>{date.toLocaleDateString()}</td>
            </tr>
          )
        })}
      </tbody>
    </table>
  </div>
);

方案2:改造ExpenseItem组件适配表格场景

调整组件根元素为tr,增加日期类型兼容处理,避免类型错误:

import './ExpenseItem.css';

function ExpenseItem(props) {
    // 兼容传入字符串格式日期的场景
    const targetDate = props.date instanceof Date ? props.date : new Date(props.date);
    return (
        <tr className="expense-item">
            <td>{targetDate.toLocaleDateString()}</td>
            <td className="expense-item__description">
                {props.title}
            </td>
            <td className="expense-item__price">{props.amount}</td>
        </tr>
    )
}

export default ExpenseItem

改造后App.js中tbody内的渲染逻辑可直接替换为组件调用:

{expenses.map((expense, index) => (
  <ExpenseItem
    key={expense.id ?? index}
    title={expense.title}
    amount={expense.amount}
    date={expense.date}
  />
))}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 13:19:05