Big*_*ble 8 javascript reactjs server-side-rendering next.js
我有一个简单的app/components/organisms/Cookies.tsx模态窗口组件,我将其导入到app/page.tsx. 我已'use client'在组件顶部添加了指令,但由于某种原因,我不断收到:
ReferenceError:本地存储未定义
我的代码Cookies.tsx:
'use client';
import { useState } from 'react';
const Cookies = () => {
const localStorageCookies = localStorage.getItem('cookies-accepted');
const [cookiesAccepted, setCookiesStatus] = useState<boolean>(!!localStorageCookies);
const acceptCookies = () => {
localStorage.setItem('cookies-accepted', 'true');
setCookiesStatus(true);
}
return (
<>
{!cookiesAccepted && (
<section className="fixed max-w-md p-4 mx-auto bg-white border border-gray-200 left-12 bottom-16 rounded-2xl z-20">
<h2 className="font-semibold text-gray-800 "> Cookie Notice</h2>
<p className="mt-4 text-sm text-gray-600">
We use cookies to ensure that we give you the best experience on our
website.{' '}
<a href="#" className="text-blue-500 hover:underline">
Read cookies policies
</a>
.{' '}
</p>
<div className="flex items-center justify-between mt-4 gap-x-4 shrink-0">
<button className="text-xs text-gray-800 underline transition-colors duration-300 hover:text-gray-600 focus:outline-none">
Manage your preferences
</button>
<button
className=" text-xs bg-gray-900 font-medium rounded-lg hover:bg-gray-700 text-white px-4 py-2.5 duration-300 transition-colors focus:outline-none"
onClick={acceptCookies}
>
Accept
</button>
</div>
</section>
)}
</>
);
};
export default Cookies;
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?我尝试将其放在文件夹Cookies.tsx之外app,但没有帮助。
我正在使用版本 Next.js 版本13.4.1。
You*_*mar 13
正如您在渲染中所读到的,实际上,服务器和客户端组件都首先在服务器上渲染,然后以 HTML 形式发送到浏览器(您可以在浏览器的网络选项卡中看到生成的 HTML 文件)。这是文档的引用:
为了优化初始页面加载,Next.js 将使用 React 的 API 在服务器上为客户端和服务器组件呈现静态 HTML 预览。这意味着,当用户第一次访问您的应用程序时,他们将立即看到页面的内容,而无需等待客户端下载、解析和执行客户端组件 JavaScript 包。
两者之间的区别在于,当您添加 时"use client",这意味着该组件包括客户端交互:因此 Next.js 应该发送所需的 JavaScript(例如事件处理程序、效果等)并将其附加到之前显示为普通的组件HTML 组件。
因此,任何特定于浏览器的内容(例如 )localStorage不应在客户端组件主体中调用,而只能在useEffect事件处理程序内部调用......
这应该适用于您的情况:
"use client";
import { useEffect, useState } from "react";
const Cookies = () => {
const [cookiesAccepted, setCookiesStatus] = useState<boolean | null>(null);
const acceptCookies = () => {
localStorage.setItem("cookies-accepted", "true");
setCookiesStatus(true);
};
useEffect(() => {
const localStorageCookies = localStorage.getItem("cookies-accepted");
setCookiesStatus(!!localStorageCookies);
}, []);
if (cookiesAccepted === null || cookiesAccepted) {
return null;
}
return (
<section className="fixed max-w-md p-4 mx-auto bg-white border border-gray-200 left-12 bottom-16 rounded-2xl z-20">
<h2 className="font-semibold text-gray-800 "> Cookie Notice</h2>
<p className="mt-4 text-sm text-gray-600">
We use cookies to ensure that we give you the best experience on our website.{" "}
<a href="#" className="text-blue-500 hover:underline">
Read cookies policies
</a>
.{" "}
</p>
<div className="flex items-center justify-between mt-4 gap-x-4 shrink-0">
<button className="text-xs text-gray-800 underline transition-colors duration-300 hover:text-gray-600 focus:outline-none">
Manage your preferences
</button>
<button
className=" text-xs bg-gray-900 font-medium rounded-lg hover:bg-gray-700 text-white px-4 py-2.5 duration-300 transition-colors focus:outline-none"
onClick={acceptCookies}
>
Accept
</button>
</div>
</section>
);
};
export default Cookies;
Run Code Online (Sandbox Code Playgroud)
并且不要尝试typeof window !== "undefined"破解,因为很可能您会收到水合错误。
| 归档时间: |
|
| 查看次数: |
2569 次 |
| 最近记录: |