客户端组件中的条件渲染触发水合错误

问题描述 投票:0回答:1

我在客户端组件中遇到条件渲染问题。每次完成条件渲染(在本例中基于 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"
}
next.js
1个回答
0
投票
  1. 您可以使用服务器组件并排除条件渲染,但要捕获 cookie 版本,您需要执行以下操作:
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/>
,而不会出现水合错误。

  1. 在您提供的上下文中,我无法理解您需要客户端组件的原因,但是您仍然可以跳过其在服务器端的渲染,直到使用 useEffect 将组件安装在客户端上,如下所示:
"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>
  );
}

这也将修复水合作用错误。

© www.soinside.com 2019 - 2024. All rights reserved.