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

Next.js + Sanity引入时间戳时出现Hydration Error求助

解决方案:Next.js SSR/ISR 中 Date.toLocaleString() 触发 Hydration Error 修复

问题根源

SSR/ISR 模式下,服务器的区域设置(locale)和客户端浏览器的 locale 几乎不可能完全一致,toLocaleString() 会根据运行环境生成不同格式的时间文本,导致服务端输出的 HTML 和客户端 hydration 时生成的 DOM 内容不匹配,触发 hydration 错误。

具体解决方法

方法1:客户端组件延迟渲染时间

把时间渲染逻辑放到客户端组件中,利用 useEffect 在 hydration 完成后再生成本地化时间:

'use client';

import { useState, useEffect } from 'react';

export default function PostDate({ createdAt }) {
  const [localizedDate, setLocalizedDate] = useState('');

  useEffect(() => {
    setLocalizedDate(new Date(createdAt).toLocaleString());
  }, [createdAt]);

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

使用时直接引入该组件并传入 post._createdAt 即可。

方法2:强制统一 locale 参数

明确指定 toLocaleString() 的 locale 参数,让服务端和客户端生成完全一致的时间格式:

// 示例:统一使用中文格式,也可替换为'en-US'等固定locale
const formattedDate = new Date(post._createdAt).toLocaleString('zh-CN');

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

注意:此方法适合固定时间格式的场景,无法自动适配用户浏览器的 locale。

方法3:动态导入禁用 SSR

通过 Next.js 的动态导入功能,让时间渲染逻辑仅在客户端执行:

import dynamic from 'next/dynamic';

// 禁用该组件的服务端渲染
const DateComponent = dynamic(() => import('./DateComponent'), {
  ssr: false,
  loading: () => <span>加载中...</span>
});

// 组件中直接使用
<DateComponent createdAt={post._createdAt} />

DateComponent 内部就是包含 toLocaleString() 渲染逻辑的普通组件。

方法4:服务端预格式化时间(ISR 场景推荐)

在 getStaticProps/getServerSideProps 中提前格式化好时间字符串,直接传递给组件渲染,彻底避免客户端和服务端的格式差异:

export async function getStaticProps() {
  // 从 Sanity 获取文章数据
  const post = await fetchPostFromSanity();
  // 服务端指定 locale 格式化时间
  post.formattedCreatedAt = new Date(post._createdAt).toLocaleString('zh-CN');
  
  return {
    props: { post },
    revalidate: 60 // ISR 自动刷新间隔(秒)
  };
}

// 组件直接使用预格式化好的字符串
export default function Post({ post }) {
  return <span>{post.formattedCreatedAt}</span>;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 03:22:40