使用date-fns按时间排序博客数组及自动设置新增时间问题
问题解决方案
一、修复排序失效问题
排序不生效的核心原因是直接使用格式化后的日期字符串转换Date对象会解析失败。比如new Date("2/13 3:48a")这种非标准格式,浏览器无法正确识别年份与完整时间信息,导致排序逻辑失效。
最优解决方法:
- 存储原始时间对象/时间戳:数据中不要存格式化后的字符串,转而存储
new Date()生成的原始Date对象,或Date.now()生成的时间戳(数字类型,排序更高效)。 - 渲染时再格式化:在页面展示阶段,用
format函数将原始时间转换成你需要的显示格式。
修改示例:
// 初始化数据时存储Date对象 const BlogTopic = [ { title: "First Post", message: "test", author: "Dagger", date: new Date(2024, 1, 13, 2, 9), // 对应2/13 2:09a }, { title: "Second Post", message: "test", author: "Dagger", date: new Date(2024, 1, 13, 3, 48), // 对应2/13 3:48a }, ]; // 组件内状态与排序逻辑 const [topic, setTopic] = useState(BlogTopic); {topic .sort((a, b) => b.date - a.date) // 直接用Date对象相减得到时间差,实现降序 .map(({ title, author, date }, index) => ( <tr> <td className="blog__topic"> <a href="/">{title}</a> </td> <td>{author}</td> <td>{format(date, "M/dd h:mma")}</td> {/* 渲染时格式化显示 */} </tr> ))}
二、新增条目时自动获取当前时间
将addTopic函数中固定的parse语句替换为直接生成当前时间的Date对象,即可自动获取提交瞬间的时间:
修改后的addTopic函数:
const addTopic = (e) => { e.preventDefault(); setTopic([ ...topic, { title: title, message, author: "Dagger", count: 1, date: new Date(), // 直接获取当前时间的Date对象 }, ]); setTitle(""); };
备选方案(不推荐):
如果因特殊需求必须存储格式化后的字符串,排序时需用parse将字符串转回Date对象再比较:
{topic .sort((a, b) => parse(b.date, "M/dd h:mma", new Date()) - parse(a.date, "M/dd h:mma", new Date())) .map(...) }
此方法效率低于存储原始时间对象,且格式变动时易出错,仅作为临时替代方案。
内容的提问来源于stack exchange,提问作者Dagger
相关产品推荐
相关产品推荐

