如何在map函数中正确渲染按日期分组的JSX元素
问题描述
我有如下对象数组形式的数据:
history = [ {item: cake, calories: 120, datetime: '2022-11-16 07:51:26'}, {item: chicken, calories: 250, datetime: '2022-11-16 13:48:46'}, {item: pizza, calories: 420, datetime: '2022-11-25 11:13:42'} ];
我希望渲染一个包含日期标题的div,并将同一日期的所有项归组到列表中。我尝试用map函数实现:
第一次尝试的代码:
function renderHistory () { let date; return props.history.map((item, i) => { const dateAdded = item.datetime.split(" ")[0]; if (date !== dateAdded) { date = dateAdded; return ( <> <div> <h2>{dateAdded}</h2> <li>{item.item} - {item.calories} calories</li> </> ) } return ( <> <li>{item.item} - {item.calories} calories</li> </div> </> ) }) }
出现错误:Expected corresponding JSX closing tag for <div>
第二次修改后的代码:
return props.history.map((item, i) => { const dateAdded = item.datetime.split(" ")[0]; if (date !== dateAdded) { date = dateAdded; return ( <div> <h2>{dateAdded}</h2> <li>{item.item} - {item.calories} calories</li> </div> ) } return ( <li>{item.item} - {item.calories} calories</li> ) })
但同日期的第二个元素会跳出div,请问如何将同一日期的所有项放入同一个div中?
解决方案
直接遍历原数组无法实现同日期元素的容器合并,正确做法是先按日期分组数组,再基于分组后的数据渲染UI。
1. 按日期分组数组
先写一个工具函数,将原数组按日期字段分组:
const groupHistoryByDate = (history) => { return history.reduce((groups, item) => { const date = item.datetime.split(" ")[0]; // 如果当前日期还没创建分组,初始化一个空数组 if (!groups[date]) { groups[date] = []; } // 将当前项加入对应日期的分组 groups[date].push(item); return groups; }, {}); };
这个函数会把原数组转换成如下结构的对象:
{ "2022-11-16": [ {item: cake, calories: 120, datetime: '2022-11-16 07:51:26'}, {item: chicken, calories: 250, datetime: '2022-11-16 13:48:46'} ], "2022-11-25": [ {item: pizza, calories: 420, datetime: '2022-11-25 11:13:42'} ] }
2. 渲染分组后的UI
修改renderHistory函数,先分组再渲染:
function renderHistory(props) { const groupedData = groupHistoryByDate(props.history); // 将分组对象的日期键转换为数组,方便遍历 return Object.keys(groupedData).map(date => ( <div key={date}> <h2>{date}</h2> <ul> {/* 注意:li必须包裹在ul/ol内,符合HTML语义规范 */} {groupedData[date].map((item, index) => ( <li key={index}>{item.item} - {item.calories} calories</li> ))} </ul> </div> )); }
关键说明
- 用
reduce分组是处理这类归组需求的标准方案,逻辑清晰且易于维护,比直接遍历原数组更可靠。 - 每个日期对应一个独立的
div容器,内部包含日期标题和该日期下的所有食物列表,完全满足同日期项归组的需求。 - 补充了
<ul>标签包裹<li>,避免出现无效的DOM结构,符合HTML规范。
内容的提问来源于stack exchange,提问作者DragonBorn
相关产品推荐
相关产品推荐

