我在客户端组件中遇到条件渲染问题。每次完成条件渲染(在本例中基于 cookie 的值)时,我都会收到以下错误:
react-dom.development.js:7076 Uncaught Error: Hydration failed because the initial UI does not match what was rendered on the server.
我不确定我是否使用了这个错误或者有错误的期望。对我来说,很明显服务器呈现了不同的标记,因为它不一定知道 cookie 的状态。我认为这就是使用客户端组件的全部意义。
这是一个说明问题的最小示例:
import Image from "next/image";
import { cookies } from "next/headers";
import ClientComponent from "@/components/client-component";
export default function Home() {
return (
<main className="p-24">
{/* <p>The current value of the cookie is: {currentVal?.value}</p> */}
<form
action={async function clearPrivilegeCookies() {
"use server";
const cookieStore = cookies();
console.log("setting cookie to a");
cookieStore.set("version", "a");
}}
>
<button type="submit">Set version to "a"</button>
</form>
<form
action={async function clearPrivilegeCookies() {
"use server";
const cookieStore = cookies();
console.log("setting cookie to b");
cookieStore.set("version", "b");
}}
>
<button type="submit">Set version to "b"</button>
</form>
<ClientComponent />
</main>
);
}
客户端组件正在读取此 cookie 并打印值
"use client";
import { getCookie } from "cookies-next";
export default function ClientComponent() {
const version = getCookie("version");
return (
<p className="text-black">The cookies is currently set to: {version}</p>
);
}
如果我使用服务器组件,它就可以工作,但这不是我需要的。
import { cookies } from "next/headers";
export default function ServerComponent() {
console.log(`Render Server Component`);
const cookiesStore = cookies();
const version = cookiesStore.get("version");
return (
<p className="text-black">The cookies is currently set to: {version?.value}</p>
);
}
当您单击任一按钮(UI 立即更新)和刷新时,就会发生错误。这将导致水合错误。但是,我假设 Next.js 不会将这种差异标记为错误。
我正在使用旧版本的最新版本
"dependencies": {
"cookies-next": "^4.1.0",
"next": "14.0.4",
"react": "^18.2.0",
"react-dom": "^18.2.0"
}
import { cookies } from "next/headers";
const ServerComponent = async () => {
const cookieVersion = cookies().get("version");
return (
<p className="text-black">
The cookie is currently set to: {cookieVersion?.value}
</p>
);
};
export default ServerComponent;
然后您可以在
<ServerComponent />
内使用 <Home/>
,而不会出现水合错误。
"use client";
import { getCookie } from "cookies-next";
import React, { useState } from "react";
export default function ClientComponent() {
const version = getCookie("version");
const [isMounted, setIsMounted] = useState(false);
React.useEffect(() => {
setIsMounted(true);
}, []);
if (!isMounted) {
return null;
}
return (
<p className="text-black">The cookies is currently set to: {version}</p>
);
}
这也将修复水合作用错误。