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

如何在React中展示含不同日期键的JSON数据?

嗨,这个问题我之前也碰到过!因为你的数据是以日期为键的对象,不是数组,所以确实没法直接用map()。不过咱们可以用JS自带的对象遍历方法把它转成可迭代的数组,之后就能轻松在React里渲染成表格或列表了。下面给你两种实用的实现方案:


方案1:分组表格展示(清晰区分日期)

这种方式会按原始数据的日期分组,同一个日期的记录归在一起,表格里还会优化日期显示(同日期只显示一次),可读性很强:

import React from 'react';

const DutyRecords = () => {
  // 你的原始数据
  const dutyData = { 
    "2020-09-19": [ 
      { end: "2020-09-19T10:30:00Z", start: "2020-09-19T06:52:10Z", user: "rakul" }, 
      { end: "2020-09-19T18:30:00Z", start: "2020-09-19T10:30:00Z", user: "jeet" }, 
      { end: "2020-09-20T02:30:00Z", start: "2020-09-19T18:30:00Z", user: "rahul" } 
    ], 
    "2020-09-22": [ 
      { end: "2020-09-20T10:30:00Z", start: "2020-09-20T02:30:00Z", user: "rakul" }, 
      { end: "2020-09-20T18:30:00Z", start: "2020-09-20T10:30:00Z", user: "jeet" }, 
      { end: "2020-09-21T02:30:00Z", start: "2020-09-20T18:30:00Z", user: "rahul" } 
    ] 
  };

  // 把对象转成 [日期字符串, 对应记录数组] 的格式,方便遍历
  const dateRecordPairs = Object.entries(dutyData);

  // 可选:如果需要按日期排序,取消下面注释
  // const sortedPairs = dateRecordPairs.sort(([dateA], [dateB]) => new Date(dateA) - new Date(dateB));

  return (
    <div style={{ padding: '2rem', maxWidth: '800px', margin: '0 auto' }}>
      <h2>值班记录表</h2>
      <table style={{ width: '100%', borderCollapse: 'collapse', marginTop: '1rem' }}>
        <thead>
          <tr style={{ backgroundColor: '#f5f5f5' }}>
            <th style={{ border: '1px solid #ddd', padding: '0.8rem' }}>日期</th>
            <th style={{ border: '1px solid #ddd', padding: '0.8rem' }}>值班人员</th>
            <th style={{ border: '1px solid #ddd', padding: '0.8rem' }}>开始时间</th>
            <th style={{ border: '1px solid #ddd', padding: '0.8rem' }}>结束时间</th>
          </tr>
        </thead>
        <tbody>
          {dateRecordPairs.map(([date, records]) => (
            records.map((record, idx) => (
              <tr key={`${date}-${idx}`} style={{ textAlign: 'center' }}>
                {/* 同一个日期下只在第一条记录显示日期,其他行留空 */}
                <td style={{ border: '1px solid #ddd', padding: '0.8rem' }}>{idx === 0 ? date : ''}</td>
                <td style={{ border: '1px solid #ddd', padding: '0.8rem' }}>{record.user}</td>
                <td style={{ border: '1px solid #ddd', padding: '0.8rem' }}>
                  {new Date(record.start).toLocaleString()}
                </td>
                <td style={{ border: '1px solid #ddd', padding: '0.8rem' }}>
                  {new Date(record.end).toLocaleString()}
                </td>
              </tr>
            ))
          ))}
        </tbody>
      </table>
    </div>
  );
};

export default DutyRecords;

关键知识点:

  • Object.entries(对象):把原始的键值对对象转换成[键, 值]格式的数组,这样就能用map()遍历了。
  • 日期显示优化:同一个日期的多条记录只在第一行显示日期,避免重复,视觉更整洁。
  • 时间格式化:用new Date().toLocaleString()把UTC时间转成用户本地的可读时间格式,你也可以根据需求换成Intl.DateTimeFormat做更精细的格式化。
  • 唯一key:每个遍历的元素都加了唯一的key,避免React渲染警告。

方案2:扁平化列表展示(不区分日期)

如果不需要按日期分组,想把所有记录放在一起展示,可以用Object.values()+flat()把所有记录合并成一个数组:

import React from 'react';

const AllDutyRecords = () => {
  const dutyData = { /* 你的原始数据 */ };
  
  // 把所有日期下的记录合并成一个数组
  const allRecords = Object.values(dutyData).flat();

  return (
    <div style={{ padding: '2rem' }}>
      <h2>所有值班记录</h2>
      <ul style={{ listStyle: 'none', padding: 0 }}>
        {allRecords.map((record, idx) => (
          <li key={idx} style={{ padding: '0.8rem', borderBottom: '1px solid #eee' }}>
            <strong>{record.user}</strong> | 
            {new Date(record.start).toLocaleString()} — {new Date(record.end).toLocaleString()}
          </li>
        ))}
      </ul>
    </div>
  );
};

export default AllDutyRecords;

额外提示:

如果你的日期键是乱序的,想要按时间先后排序,可以在遍历前对dateRecordPairs排序,比如:

const sortedPairs = dateRecordPairs.sort(([dateA], [dateB]) => new Date(dateA) - new Date(dateB));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 12:22:50