警告:文本内容不匹配。服务器:"I'm out" 客户端:"I'm in" div
Warning: Text content did not match. Server: "I'm out" Client: "I'm in" div
我在 Next.js 项目中使用 universal-cookie
,这是 return 在控制台中发出警告的简单代码:
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>
);
}
当“I'M IN”然后刷新页面时,控制台中出现以下警告:
我已经到处寻找解决方案。
Next.js pre-renders every page 在服务器上。
This means that Next.js generates HTML for each page in advance,
instead of having it all done by client-side JavaScript.
(...) When a
page is loaded by the browser, its JavaScript code runs and makes the
page fully interactive. (This process is called hydration.)
在浏览器上呈现的 HTML 与在服务器上生成的不匹配,因为两者 cook.get("key")
returns 不同。
有几个选项可以解决这个问题。
#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
与 { ssr: false }
结合使用
作为替代解决方案,也可以通过使用 { ssr: false }
动态导入带有 next/dynamic
的 React 组件来规避该问题,无论该组件在何处使用。这可以防止组件包含在服务器上,并仅在客户端动态加载它。
const Home = dynamic(
() => import('../components/Home'),
{ ssr: false }
)
在 html 元素(不同)上使用 suppresshydrationwarning
属性对我有用。根据以下文档,它仅在单个级别起作用:
https://reactjs.org/docs/dom-elements.html#suppresshydrationwarning
我在 Next.js 项目中使用 universal-cookie
,这是 return 在控制台中发出警告的简单代码:
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>
);
}
当“I'M IN”然后刷新页面时,控制台中出现以下警告:
我已经到处寻找解决方案。
Next.js pre-renders every page 在服务器上。
This means that Next.js generates HTML for each page in advance, instead of having it all done by client-side JavaScript.
(...) When a page is loaded by the browser, its JavaScript code runs and makes the page fully interactive. (This process is called hydration.)
在浏览器上呈现的 HTML 与在服务器上生成的不匹配,因为两者 cook.get("key")
returns 不同。
有几个选项可以解决这个问题。
#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
与 { ssr: false }
结合使用
作为替代解决方案,也可以通过使用 { ssr: false }
动态导入带有 next/dynamic
的 React 组件来规避该问题,无论该组件在何处使用。这可以防止组件包含在服务器上,并仅在客户端动态加载它。
const Home = dynamic(
() => import('../components/Home'),
{ ssr: false }
)
在 html 元素(不同)上使用 suppresshydrationwarning
属性对我有用。根据以下文档,它仅在单个级别起作用:
https://reactjs.org/docs/dom-elements.html#suppresshydrationwarning