Next/React 功能性 React 组件中的 Hydration Failed 错误

Next/React Hydration Failed Error in a functional React component

我有一个 Next/React 组件,它是一个计时器,它从用户到达该组件的 new Date() 时间开始。然后在计时器变为 0 后重置,开始下一小时的倒计时。我收到来自 Next.js 的错误,我不确定如何解决它,因为我正在使用错误控制台中提供的建议 useEffect and useState

错误:警告:文本内容不匹配。服务器:“34” 客户端:“33”

错误:未捕获错误:Hydration 失败,因为初始 UI 与服务器上呈现的内容不匹配。

import { useState, useEffect } from 'react';
import styles from '../styles/App.module.css';

const Timer = () => {
  const now: Array<string> = new Date().toISOString()
    .split('.')[0]
    .split(':')

  const nowMin: number = parseInt(now[1]) * 60000,
    nowSec: number = parseInt(now[2]) * 1000,
    hour: number = 3600000, // one hour in milliseconds
    startTime: number = hour - (nowMin + nowSec),
    time: number = hour

  const [counter, setCounter] = useState(startTime)

  useEffect(() => {
    const timer = counter > 0 &&
      setInterval(() => {
        setCounter(counter - 1000)
      }, 1000)
    return () => clearInterval(timer as any)
  }, [counter])

  if (counter === 0) {
    setCounter(time)
  }

  return (
    <div className={styles.timer}>
      <span className={`${styles.code} ${styles.minutes}`}>
        {
          String(Math.floor((counter % (1000 * 60 * 60)) / (1000 * 60)))
            .padStart(2, '0')
        }
      </span>
      <span className={styles.colon}>:</span>
      <span className={`${styles.code} ${styles.seconds}`}>
        {
          String(Math.floor((counter % (1000 * 60)) / 1000))
            .padStart(2, '0')
        }
      </span>
    </div>
  )
}

export default Timer

我找到了解决办法。您可以在 Next.js 中 disable server side rendering。在导入 Timer 组件的组件上,禁用 ssr 消除了该错误。我希望这可以帮助 运行 的任何其他人进入水化反应错误:

const Timer = dynamic(() => import('../components/timer'), {
  ssr: false
})

...

<Timer />