skip to Main Content

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

2

Answers


  1. Try suppressHydrationWarning, this should fix hydration issue

    Login or Signup to reply.
  2. 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,
    })
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search