【问题标题】:How to solve hydration errors related to dates in a React / Remix application?如何解决 React / Remix 应用程序中与日期相关的水合作用错误?
【发布时间】:2023-01-30 22:52:57
【问题描述】:

我正在构建一个应用程序作为一个业余项目,并努力尝试学习服务器呈现的 React,但我偶然发现了一个看似容易修复的错误,但我不知道我应该如何解决这个问题。使用混音 1.10。

当我的代码运行时,它是有缺陷的。服务器呈现一件事而客户端呈现另一件事,导致呈现的元素在页面加载时闪烁。它还会在控制台中引发大量错误,例如:

未捕获的错误:补水时出错。因为错误发生在 Suspense 边界之外,所以整个根将切换到客户端呈现。

24x react-dom.development.js:12507 未捕获错误:Hydration 失败,因为初始 UI 与服务器上呈现的内容不匹配。

react_devtools_backend.js:4012 警告:文本内容不匹配。服务器:“1/29/2023,上午 10:44:09” 客户端:“1/29/2023,下午 12:44:09”

服务器在 UTC 时区,但客户端可以是任何东西。在这种情况下,它是 GMT+2。我应该怎么办?我想我可以将服务器时区设置为客户端时区,但我也认为这可能是个糟糕的主意。

我能做的最好的准系统简化示例就是这个。

// routes/example.tsx
import { useLoaderData } from "@remix-run/react"
import {json, LoaderArgs } from "@remix-run/server-runtime"

export async function loader({ request }: LoaderArgs) {
  const timestampFromDB = "2023-01-29T10:44:09.672Z"
  
  return json({ time: timestampFromDB })
}

export default function HydrationError() {
  const loaderData = useLoaderData<typeof loader>()
  const time = new Date(loaderData.time)
  const stamp = time.toLocaleString("en-US")

  return (
    <div>
      Time: 

      <time>{stamp}</time>
    </div>
  )
}

我试图在提问之前寻找答案,但我找到的最接近的东西甚至与我的问题不相符; Remix Hydration failed: UI on server and client do not match。就我而言,它在本地不好,根本不好。

【问题讨论】:

    标签: reactjs server-side-rendering remix.run


    【解决方案1】:

    toLocaleString 规范允许跨实现的输出变化,因此您最好避免使用客户端的实现,而是通过将 toLocaleString 移至加载程序来使用服务器的实现。

    // routes/example.tsx
    import { useLoaderData } from "@remix-run/react"
    import {json, LoaderArgs } from "@remix-run/server-runtime"
    
    export async function loader({ request }: LoaderArgs) {
      const timestampFromDB = "2023-01-29T10:44:09.672Z"
      
      return json({ stamp: new Date(timestampFromDB).toLocaleString('en-US') })
    }
    
    export default function HydrationError() {
      const { stamp } = useLoaderData<typeof loader>()
    
      return (
        <div>
          Time: 
    
          <time>{stamp}</time>
        </div>
      )
    }
    

    或者,您可能想看看Intl.DateTimeFormat,它可以让您更好地控制日期呈现,并可能提供更高的一致性。

    React Intl 是建立在Intl.DateTimeFormat 之上的库,值得一试。

    【讨论】:

      猜你喜欢
      • 2021-08-02
      • 2019-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-16
      • 1970-01-01
      • 2021-12-15
      相关资源
      最近更新 更多