乐趣区

关于ssr: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 ? <AuthenticatedNav /> : <UnauthenticatedNav />}

解决二

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() ? <AuthenticatedNav /> : <UnauthenticatedNav />
}
退出移动版