You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NextJS 日期时间计数器Hydration问题求助

Next.js 日期时间计数器的 Hydration 问题解决

你遇到的这个警告是典型的服务端渲染(SSR)与客户端 Hydration 内容不匹配问题,原因很直接:

  • 服务端渲染页面时,会执行useState的初始化函数生成一个时间字符串(比如01:07:28)
  • 当客户端拿到页面开始 Hydrate 时,时间已经过去了几秒(哪怕1秒),此时客户端执行同样的初始化函数会生成新的时间(比如01:07:29)
  • 两者文本内容不一致,触发了 Next.js 的 Hydration 不匹配警告

下面是两种简单有效的解决方案:

方案1:用 useEffect 在客户端初始化时间

useEffect只会在客户端执行,服务端不会运行。我们可以先给currentTime设置一个服务端渲染的占位符,客户端再替换成真实时间:

import { useState, useEffect } from "react";

function MyApp({ Component, pageProps }) {
  // 服务端渲染时显示占位符,避免内容不匹配
  const [currentTime, setCurrentTime] = useState("00:00:00");

  useEffect(() => {
    // 仅在客户端执行,初始化当前时间
    const updateTime = () => {
      const hour = ("0" + new Date().getUTCHours()).slice(-2);
      const minutes = ("0" + new Date().getUTCMinutes()).slice(-2);
      const seconds = ("0" + new Date().getUTCSeconds()).slice(-2);
      setCurrentTime(`${hour}:${minutes}:${seconds}`);
    };
    
    // 初始化一次
    updateTime();
    // 如果需要实时更新时间,添加定时器
    const interval = setInterval(updateTime, 1000);
    // 组件卸载时清除定时器
    return () => clearInterval(interval);
  }, []);

  return (
    <span>{currentTime}</span>
  );
}

export default MyApp;

方案2:用 dynamic 组件禁用 SSR

把时间计数器做成独立组件,然后通过dynamic导入并禁用服务端渲染,让组件完全在客户端运行:

第一步:创建独立的 Clock 组件

// components/Clock.js
import { useState, useEffect } from "react";

export default function Clock() {
  const [currentTime, setCurrentTime] = useState(() => {
    const hour = ("0" + new Date().getUTCHours()).slice(-2);
    const minutes = ("0" + new Date().getUTCMinutes()).slice(-2);
    const seconds = ("0" + new Date().getUTCSeconds()).slice(-2);
    return `${hour}:${minutes}:${seconds}`;
  });

  useEffect(() => {
    // 实时更新时间
    const interval = setInterval(() => {
      const hour = ("0" + new Date().getUTCHours()).slice(-2);
      const minutes = ("0" + new Date().getUTCMinutes()).slice(-2);
      const seconds = ("0" + new Date().getUTCSeconds()).slice(-2);
      setCurrentTime(`${hour}:${minutes}:${seconds}`);
    }, 1000);
    return () => clearInterval(interval);
  }, []);

  return <span>{currentTime}</span>;
}

第二步:在 MyApp 中动态导入

import dynamic from 'next/dynamic';

// 禁用 SSR,组件仅在客户端渲染
const Clock = dynamic(() => import('../components/Clock'), { ssr: false });

function MyApp({ Component, pageProps }) {
  return (
    <Clock />
  );
}

export default MyApp;

内容的提问来源于stack exchange,提问作者connorhansen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 12:03:38