我在用着universal-cookie
在 Next.js 项目中,这是在控制台中返回警告的简单代码:
import React, { useState } from "react";
import Cookies from "universal-cookie";
import styles from "../styles/Home.module.css";
export default function Home() {
const cook = new Cookies();
const [session, setSession] = useState(cook.get("key"));
const setCookie = () => {
cook.set("key", "hola", { secure: true });
setSession(cook.get("key"));
};
const deleteCookie = () => {
cook.remove("key", { secure: true });
setSession(undefined);
};
return (
<div className={styles.container}>
<button onClick={() => setCookie()}>Save Cookie</button>
<button onClick={() => deleteCookie()}>Delete Cookie</button>
{session ? <>I'm in</> : <>I'm out</>}
</div>
);
}
当“我在”然后刷新页面时,控制台中会出现以下警告:
我已经到处寻找解决方案。
Next.js 预渲染服务器上的每个页面。
默认情况下,Next.js预渲染每一页。这意味着Next.js提前为每个页面生成HTML,
而不是全部由客户端 JavaScript 完成。
预渲染可以带来更好的性能和 SEO。
(...) 当一个
页面由浏览器加载,其 JavaScript 代码运行并使得
页面完全交互(这个过程称为水合作用 https://react.dev/reference/react-dom/client/hydrateRoot在反应中)。
— Next.js,构建您的应用程序,渲染 https://nextjs.org/docs/pages/building-your-application/rendering
出现水合作用问题的原因是浏览器上呈现的 HTML 与服务器上生成的 HTML 不匹配。在你的情况下,这是因为cook.get("key")
两者返回不同的东西。
有几个选项可以解决这个问题。
#1 将设置状态移至useEffect
第一个解决方案是将状态设置移动到useEffect
。这会强制仅在客户端设置状态,因此不会发生不匹配。
export default function Home() {
const cook = new Cookies();
const [session, setSession] = useState();
// `setCookie` and `deleteCookie` code here
useEffect(() => {
setSession(cook.get("key"));
}, []);
return (
<div className={styles.container}>
<button onClick={() => setCookie()}>Save Cookie</button>
<button onClick={() => deleteCookie()}>Delete Cookie</button>
{session ? <>I'm in</> : <>I'm out</>}
</div>
);
}
#2 使用next/dynamic
with { ssr: false }
作为替代解决方案,还可以通过动态导入 React 组件来规避该问题next/dynamic https://nextjs.org/docs/advanced-features/dynamic-import#with-no-ssr using { ssr: false }
,无论在哪里使用该组件。这可以防止组件包含在服务器上,并且仅在客户端动态加载它。
const Home = dynamic(
() => import('../components/Home'),
{ ssr: false }
)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)