我有一个身份验证组件,可以检查用户是否有来自localstorage的token,下面是我的代码:
import { useRouter } from "next/router";
import { useState } from "react";
const Index = (WrappedComponent: any) => {
return (props: any) => {
if (typeof window !== "undefined") {
const Router = useRouter();
const accessToken = localStorage.getItem("token");
if (!accessToken) {
Router.replace("/authentication/login");
return null;
}
return <WrappedComponent {...props} />;
}
// If we are on server, return null
return null;
};
};
export default Index;
我在/pages目录中使用它来创建我的组件,如下所示:
import PageContainer from "../src/components/container/PageContainer";
import FullLayout from "../src/layouts/full/FullLayout";
import ShortList from "@/src/components/dashboard/ShortList";
import withAuth from "@/src/auth";
const Index = () => {
return (
<FullLayout>
<PageContainer title="Sample Page" description="this is Sample page">
<ShortList />
</PageContainer>
</FullLayout>
);
};
export default withAuth(Index);
但我得到了这个错误:错误:由于初始UI与在服务器上呈现的UI不匹配,水合失败。
我该怎么解决这个问题?
我的Next.js版本是13。
我尝试使用useState,但不起作用
1条答案
按热度按时间kb5ga3dv1#
在服务器上,
typeof window
将是undefined
,但在客户端上,即使在初始渲染之前,window
也不会再被定义,这会导致一个水化错误,因为你的服务器渲染的HTML与React在水化过程中呈现的HTML不同。因为
useEffect
只在服务器上运行,你可以通过以下方式检查你是在客户端还是服务器上:一般来说,这种检查:
if (typeof window !== "undefined")
总是导致错误,不能按预期工作。我推荐这篇来自约书亚Comeau的关于React水合/再水合问题的文章https://www.joshwcomeau.com/react/the-perils-of-rehydration/#dynamic-sections-4
请记住,在这个例子中,索引页面最初将完全空白,因为它本质上是客户端呈现的,这可能会损害SEO。
要解决这个问题,您应该将auth数据存储在cookie中,并在next.js
middleware
中检查用户是否登录,并可能在中间件内部而不是客户端重定向。