欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 文化 > React SSR + Redux 导致的 Hydration 报错踩坑记录与修复方案

React SSR + Redux 导致的 Hydration 报错踩坑记录与修复方案

2025/4/24 15:31:50 来源:https://blog.csdn.net/m0_37609579/article/details/147460541  浏览:    关键词:React SSR + Redux 导致的 Hydration 报错踩坑记录与修复方案

一条“Hydration failed”的错误,让我损失了半天时间
在这里插入图片描述

背景

我在用 Next.js App Router + Redux 开发一个任务管理应用,一切顺利,直到打开了 SSR(服务端渲染),突然看到这个令人头皮发麻的报错:

Hydration failed because the server rendered HTML didn't match the client.

报错定位在 <Header />,但实际问题比看上去复杂得多。


问题原因

React SSR 会先在服务端输出 HTML,再在浏览器执行 hydration,如果服务端和客户端渲染的 DOM 结构不一致,就会报错。

Redux 的状态通常在客户端初始化,比如 auth.isAuthenticated,在 SSR 阶段它通常是 false,但客户端可能已经是 true

举个例子:

{isAuthenticated ? (<span>欢迎,{user?.username}</span>
) : (<Link href=\"/login\">登录</Link>
)}

服务端输出:

<a href=\"/login\">登录</a>

客户端切换成:

<span>欢迎,Luke</span>

标签类型完全不一样,React hydration 直接炸了。


修复方式:引入 useIsClient
import { useEffect, useState } from 'react';export function useIsClient() {const [isClient, setIsClient] = useState(false);useEffect(() => setIsClient(true), []);return isClient;
}

然后在你的组件中:

const isClient = useIsClient();if (!isClient) return null; // 跳过 SSR 阶段return isAuthenticated ? (<span>欢迎,{user?.username}</span>
) : (<Link href=\"/login\">登录</Link>
);

这样 React SSR 阶段就不会渲染出错误结构,hydration 就能成功。


更进一步:封装 ClientOnly 组件
function ClientOnly({ children }: { children: React.ReactNode }) {const isClient = useIsClient();if (!isClient) return null;return <>{children}</>;
}

任何你想跳过 SSR 的组件,只需要这样写:

<ClientOnly><Header />
</ClientOnly>

结语

React SSR + Redux 状态管理配合 App Router 使用,确实不够“傻瓜式”。但一旦你掌握了客户端条件渲染与状态保护的技巧,这种问题就能快速应对。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词