英文:
Hydration error even after adding the fuction to the useEffect in Next JS 13
问题
使用下面的代码创建一个导航菜单,显示当前日期和时间,尽管组件是客户端组件,并且使用了 useEffect:
### /src/components/navigation/index.tsx
'使用客户端'
import Link from 'next/link'
import React, { useEffect, useState } from 'react'
export default function Navigation() {
  // 时间
  const [time, setTime] = useState(new Date().toLocaleTimeString())
  useEffect(() => {
    const locale = 'en'
    const updateFormattedTime = () => {
      const today = new Date()
      const formattedTime = today.toLocaleTimeString(locale, {
        day: 'numeric',
        month: 'numeric',
        year: 'numeric',
        hour: 'numeric',
        hour12: true,
        minute: 'numeric',
        timeZone: 'Asia/Kolkata'
      })
      setTime(formattedTime)
    }
    updateFormattedTime()
    const timer = setInterval(() => {
      updateFormattedTime()
    }, 60000)
    return () => {
      clearInterval(timer)
    }
  }, [])
  return (
    <div className="navigation">
      <Link href="/">
        OUTDATED
      </Link>
      <Link href="/information">
        Information
      </Link>
      {time && <p className="information red">{time.replace(/\//g, ',')}</p>}
    </div>
  )
}
它基本上只是获取日期和时间并将其推送到状态,然后在标题本身显示它,并且只是用逗号替换斜杠。
确切的错误消息:
错误:文本内容与服务器呈现的 HTML 不匹配。
警告:文本内容不匹配。服务器端:"5:43:50 PM" 客户端:"5:43:51 PM"
详细信息请参见:https://nextjs.org/docs/messages/react-hydration-error
英文:
Using next 13 and making a navigation menu which shows the current date and time and I'm getting hydration error although the component is a client component and also Is using useEffect
### /src/components/navigation/index.tsx
'use client'
import Link from 'next/link'
import React, { useEffect, useState } from 'react'
export default function Navigation() {
  // Time
  const [time, setTime] = useState(new Date().toLocaleTimeString())
  useEffect(() => {
    const locale = 'en'
    const updateFormattedTime = () => {
      const today = new Date()
      const formattedTime = today.toLocaleTimeString(locale, {
        day: 'numeric',
        month: 'numeric',
        year: 'numeric',
        hour: 'numeric',
        hour12: true,
        minute: 'numeric',
        timeZone: 'Asia/Kolkata'
      })
      setTime(formattedTime)
    }
    updateFormattedTime()
    const timer = setInterval(() => {
      updateFormattedTime()
    }, 60000)
    return () => {
      clearInterval(timer)
    }
  }, [])
  return (
    <div className="navigation">
      <Link href="/" className="head animate">
        OUTDATED
      </Link>
      <Link href="/information" className="head animate">
        Information
      </Link>
      {time && <p className="information red">{time.replace(/\//g, ',')}</p>}
    </div>
  )
}
It basically just get the date and time and pushes it to a state and shows it on the the header itself. and I just replace the slash with commas
The extact error message
Error: Text content does not match server-rendered HTML.
Warning: Text content did not match. Server: "5:43:50 PM" Client: "5:43:51 PM"
See more info here: https://nextjs.org/docs/messages/react-hydration-error
答案1
得分: 0
尝试使用suppressHydrationWarning,这应该可以解决水合问题。
英文:
Try suppressHydrationWarning, this should fix hydration issue
答案2
得分: 0
水合作用会导致组件渲染两次。一次在预渲染中,然后再在浏览器渲染中。这会导致您的 setInterval 运行两次。
解决这个问题的一种方法是在导入该组件时禁用 ssr:
import dynamic from 'next/dynamic'
const Navigation = dynamic(() => import('@/components/navigation'), {
  ssr: false,
})
英文:
Hydration causes the component to render twice. Once in the pre-render and then again in the browser render. Causing your setInterval to run twice.
One way around this is to disable ssr for this component where you import it:
import dynamic from 'next/dynamic'
const Navigation = dynamic(() => import('@/components/navigation'), {
ssr: false,
})
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论