Hydration failed because the initial UI does not match...

Error

Hydration failed because the initial UI does not match what was rendered on the server.

原因

在呈现您的应用程序时,预呈现的 React 树 (SSR/SSG) 与在浏览器中首次呈现期间呈现的 React 树之间存在差异。
第一个渲染称为 Hydration,这是 React 的一个特性。
这可能会导致 React 树与 DOM 不同步,并导致出现意外的内容/属性。

注:
还有一种水合错误原因是,Nextjs中并不建议使用p标签中包裹div标签,如果出现如此结构,那么也将导致出现错误。
此外,antd的Typography 组件默认是p标签,当对此使用时,那么也可能会导致出现此类问题。

水合作用是什么?为什么使用它?

服务器端渲染(SSR)被 nextjs 等框架用来提高性能(LCP 和 FCP)和用户体验(SEO),它首先在服务器上渲染应用程序。它向用户返回一个完整格式的 HTML 文档,但应用程序是“动态的”,并不是所有事情都可以通过 HTML 和 CSS 完成,所以我们告诉 React 将事件处理程序附加到 HTML 以使应用程序具有交互性。
这个渲染我们的组件和附加事件处理程序的过程被称为“水化”。这就像用交互性(JS)的“水”浇灌“干燥”的 HTML。水合作用后,我们的应用程序变得交互式或“动态”。
hydration 和 rehydration 通常可以互换使用,但是在 rehydration 期间,它在用户的设备上运行,并构建了一幅世界应该是什么样子的图画。然后将其与文档中内置的 HTML 进行比较。这是一个称为再水合的过程。

在再水合中,React 假设 DOM 不会改变。它只是试图适应现有的 DOM。
当 React 应用程序重新水合时,它假定 DOM 结构将匹配。如果不是那么你知道将会出现问题。

用大白话来说就是,服务端渲染了一幅dom结构,然后浏览器端又根据某个状态重新渲染了一副dom结构,这时候就会发生,前后两幅结构进行融合(再水合),ssr默认结构是不变的,但是如果结构发生了改变,那么问题就出现了!

解决一

export default function Nav() {
  const [hasMounted, setHasMounted] = React.useState(false);
  React.useEffect(() => {
    setHasMounted(true);
  }, []);
  if (!hasMounted) {
    return null;
  }
  const user = getUser();
{user ?  : }

解决二

export function UserState() {
 const { user } = useUser();
 const [isUserLoggedIn, setIsUserLoggedIn] = useState(false);
  useEffect(() => {
     setIsUserLoggedIn(!!user);
   }, [user]);
  return isUserLoggedIn;
}
import { UserState } from './userProvider'

export default function Nav() {
 UserState() ?  : 
}

你可能感兴趣的:(Hydration failed because the initial UI does not match...)