typescript 服务器错误:文本内容与服务器呈现的HTML不匹配,U+202F与U+0020

6ie5vjzr  于 2023-02-13  发布在  TypeScript
关注(0)|答案(1)|浏览(217)

我正在使用dates和Next.js。下面是我得到的三个错误:
Warning: Text content did not match. Server: "Tuesday, January 24, 2023 at 11:01 AM" Client: "Tuesday, January 24, 2023 at 11:01 AM"
Error: Hydration failed because the initial UI does not match what was rendered on the server.
Error: There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.
我相信最后两个是在第一个之后自然出现的。
正如您可能已经注意到的,不匹配服务器和客户端的文本是相同的,但是,我注意到“11:01”和“AM”之间的空间对于服务器是一个窄的无中断空间(U+202F),对于客户端是一个空间(U+0020)。
我正在使用getServerSideProps,如下所述:

export async function getServerSideProps() {
  const eventsResult = (await prisma.event.findMany()).slice(0, 3);
  const newsResult = (await prisma.news.findMany()).slice(0, 3);

  return {
    props: {
      events: JSON.parse(JSON.stringify(eventsResult)),
      news: JSON.parse(JSON.stringify(newsResult)),
      backgroundColor: "red",
    },
  };
}

一开始,我以为它可能与JSON.parse和JSON.stringify有关,所以,我改变了它,但运气不好:

export async function getServerSideProps() {
  const eventsResult = (await prisma.event.findMany()).slice(0, 3);
  const newsResult = (await prisma.news.findMany()).slice(0, 3);

  const formattedEventsResults = eventsResult.map((e) => ({
    ...e,
    start: e.start.toString(),
    end: e.start.toString(),
  }));

  const formattedNewsResult = newsResult.map((n) => ({
    ...n,
    datetime: n.datetime.toString(),
  }));

  return {
    props: {
      events: formattedEventsResults,
      news: formattedNewsResult,
      backgroundColor: "red",
    },
  };
}

组件中显示上述日期的确切行是:
(我试图避免时区转换,因为所有的日期都是一个简单的项目使用所有的假数据。我只需要存储和显示的值相匹配)

{new Date(props.start).toLocaleString(undefined, {
  timeZone: "UTC",
  year: "numeric",
  month: "long",
  day: "2-digit",
  weekday: "long",
  hour: "2-digit",
  minute: "2-digit",
})}

如何确保服务器和客户端呈现相同的字符并避免水合错误?

xxhby3vn

xxhby3vn1#

我也在这个问题上花了几个小时,最后我用标准空格替换了格式化日期中的所有空格,解决了这个问题。

const myFormattedDate = new Date().toLocaleString(undefined, {
  timeZone: "UTC",
  year: "numeric",
  month: "long",
  day: "2-digit",
  weekday: "long",
  hour: "2-digit",
  minute: "2-digit",
}).replace(/\s/g, ' ')

相关问题