欲望:
- 在使用服务器端渲染 (SSR) 和 next.js 时,您希望在不同页面之间移动时保持状态。例如,您希望在页面之间移动时显示用户的个人资料图片。
初步实施:
- 您将数据保存到用户浏览器的本地存储中。您正在使用 Zusand 来执行此操作。
问题:
- 您看到一条错误消息,指出客户端内容与服务器呈现的 html 不匹配。来自 next.js 的示例:
# Unhandled Runtime Error
Error: Text content does not match server-rendered HTML. See more info here: [https://nextjs.org/docs/messages/react-hydration-error](https://nextjs.org/docs/messages/react-hydration-error)
解决方案:
- 当客户端 html 不同时,在组件/页面首次呈现 html 后从本地存储中加载变量。要使用 next.js 解决此问题,请仅在
useEffect 挂钩中从本地存储加载数据(相当于 Nuxt/Vue 中的 onMounted)。
- 以 Jotai 为例:
// store.js
import { atomWithStorage } from 'jotai/utils'
export const countAtom = atomWithStorage('countAtom', 0);
// pages/login.js
import {useAtom} from "jotai";
import {countAtom} from "../stores/store";
import { useEffect, useState} from "react";
export default function Login(props) {
const [count, setCount] = useAtom(countAtom); // This gets the data from the store.
const add1 = () => {
setCount((count) => count + 1);
};
const [displayedCount, setDisplayedCount] = useState(); // Set a local variable.
useEffect(() => {
setDisplayedCount(count); // Set the local variable from our store data.
}, [count])
return (
<div >
<Head>
<title>Login</title>
</Head>
<main>
<p>
{ displayedCount }
Hello from the login
<button onClick={add1}>Add 1</button>
</p>
</main>
</div>
)
}
// pages/index.js
import {useAtom} from "jotai";
import {countAtom} from "../stores/store";
import { useEffect, useState} from "react";
export default function Home(props) {
const [count, setCount] = useAtom(countAtom); // This gets the data from the store.
const add1 = () => {
setCount((count) => count + 1);
};
const [displayedCount, setDisplayedCount] = useState(); // Set a local variable.
useEffect(() => {
setDisplayedCount(count); // Set the local variable from our store data.
}, [count])
return (
<div >
<Head>
<title>Home</title>
</Head>
<main>
<p>
{ displayedCount }
Hello from the home page
<button onClick={add1}>Add 1</button>
</p>
</main>
</div>
)
}