如何在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
相关产品推荐
相关产品推荐

