reactjs 使用date-fns按时间和日期对数组排序

cclgggtu  于 2023-02-18  发布在  React
关注(0)|答案(1)|浏览(181)

我有一个包含博客文章的数组,我希望按最新条目排序。我可以很好地Map数组,但我希望最新条目位于页面的最顶部,现在它将位于底部。如果我按时间/日期排序数组,我知道它会工作,但排序时会出现问题。

const BlogTopic = [
  {
    title: "First Post",
    message: "test",
    author: "Dagger",
    date: format(new Date(), "2/13 2:09a"),
  },
  {
    title: "Second Post",
    message: "test",
    author: "Dagger",
    date: format(new Date(), "2/13 3:48a"),
  },
];

我还使用了form来添加新条目,它保存了上面所有的信息,并在数组的末尾添加了一个新对象,当需要添加日期时,我使用了这种格式。

date: format(new Date(), "M/dd h:mma"),

这是排序数组的代码。

const [topic, setTopic] = useState(BlogTopic);

{topic
  .sort((a, b) => new Date(b.date) - new Date(a.date))
  .map(({ title, author, date }, index) => (
     <tr>
       <td className="blog__topic">
         <a href="/">{title}</a>
       </td>
       <td>{author}</td>
       <td>{date}</td>
     </tr>
   ))}
    • 更新**

这是我的完整状态。有什么想法我可以改变下面的2/17 3:48a,使它自动采用当前的日期和时间?

const [title, setTitle] = useState();

  const addTopic = (e) => {
    e.preventDefault();
    setTopic([
      ...topic,
      {
        title: title,
        message,
        author: "Dagger",
        count: 1,
        date: parse("2/17 3:48a", "M/dd h:mma", new Date()),
      },
    ]);
    setTitle("");
  };
kupeojn6

kupeojn61#

好的,那么,你的代码有一些问题。我会尽量把你的代码简化到最简单的形式来解决它们,然后按照你的期望工作。
让我们从数组对象中的日期开始简化,对于第一个对象,您有format(new Date(), "2/13 2:09a"),假设您声明格式是M/dd h:mma,我可以很容易地将此日期转换为ISO格式:2023/02/13 02:09:00。这样做的好处是可以非常容易地将其馈送到new Date()。如果我们对这两个对象应用这些操作,则会得到结果数组:

const BlogTopic = [
  {
    title: "First Post",
    message: "test",
    author: "Dagger",
    date: new Date("2023/02/13 02:09:00"),
  },
  {
    title: "Second Post",
    message: "test",
    author: "Dagger",
    date: new Date("2023/02/13 03:48:00"),
  },
];

好的,到目前为止一切顺利。现在,让我们进入下一个环节:sorting。由于日期现在是一个Date对象,所以sorting很简单。实际上,您已经提供了用于sorting的代码,您只需要反转操作数:

BlogTopic.sort((a, b) => b.date - a.date)

请注意以下事项:

  • 我保持了参数的顺序,就像您使用的a, b一样
  • 我将减法b - a替换为a - b
  • 由于date参数已经是一个Date对象,因此我们不需要再次 Package 它

很好!现在我们有了一个正确排序的数组。下一步是显示这个数组。正如您所看到的,如果您尝试{new Date()},React会抱怨,因为您试图显示一个对象。因此,我们需要做的是在将这个对象提供给React之前将其转换为某种字符串表示。现在,我们将保持简单,并使用toUTCString()方法(这只是为了简化你的代码,继续阅读你期望的解决方案)。所以,现在,我们可以做以下事情(同样,请记住,为了解释所有这些,我简化了代码,我知道还有其他参数,如titleauthor);

BlogTopic.map(({ date }) => (
  <tr><td>{date.toUTCString()}</td></tr>
)}

很好!到目前为止,我们已经成功地创建了一个包含日期的数组,对它进行排序并显示它,最后一步是使用您需要的格式。正如您所指出的,我们将使用date-fns来帮助我们完成这一步。在许多其他方法中,这个库有以下两种方法我们将使用:

  • format:它接受Date对象和模式字符串,并以给定格式输出日期字符串
  • parse:接受一个带有日期的字符串、一个声明当前日期格式的模式和一个提供默认值的Date对象

这些函数的好处是它们对模式字符串使用相同的格式......这很方便!
让我们把注意力集中在数据输入上,这是你的数组,你需要把一个包含日期的字符串(例如,“2/13 2:09 a”)转换成Date对象,这意味着,从这些函数中,你需要parse,让我们用这个函数重写数组:

const BlogTopic = [
  {
    title: "First Post",
    message: "test",
    author: "Dagger",
    date: parse("2/13 2:09a", "M/dd h:mma", new Date()),
  },
  {
    title: "Second Post",
    message: "test",
    author: "Dagger",
    date: parse("2/13 3:48a", "M/dd h:mma", new Date()),
  },
];

这样做的好处是,因为parse返回一个Date对象,所以我们之后执行的任何操作(比如排序本身)都可以保持原样,因为我们没有更改预期的数据类型。
最后,为了显示日期,我们需要一个函数来获取Date对象并将其转换为字符串,这就是format函数的工作:

BlogTopic.map(({ date }) => (
  <tr><td>{format(date, "M/dd h:mma")}</td></tr>
)}

这样你就有了!如果你沿着都在遵循,你现在应该有了一个按照你期望的方式工作的代码。

相关问题