我正在使用nextJS14
⨯ 节点模块 外部验证 eact\index.js (113:10) @ useSession ⨯ 错误:React Context 在服务器组件中不可用 在家 (./app/page.tsx:18:90) 在字符串化() 摘要:“38333500” 空
//Page.tsx
import Documents from "@/components/Documents";
import Header from "@/components/Header";
import Hero from "@/components/Hero";
import Login from "@/components/Login";
import { useSession, getSession } from "next-auth/react";
export default function Home() {
const { data: session } = useSession({ required: true });
if (!session) return <Login />;
return (
<div>
<Header />
<Hero />
<Documents />
</div>
);
}
//Layout.tsx
import type { Metadata } from "next";
import { SessionProvider } from "next-auth/react";
import { Inter } from "next/font/google";
import "./globals.css";
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: "Google Docs",
description: "Generated by create next app",
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body className={inter.className}>{children}</body>
</html>
);
}
尽快回复
您遇到的问题与您尝试访问上下文不可用的服务器组件内的某些上下文(在本例中为您的会话)有关。我建议您创建一个客户端组件来为您检查这一点:
"use client"; // this makes this component a client component
import { useEffect } from "react";
import { useRouter } from "next/navigation";
import { useSession } from "next-auth/react";
interface Props extends React.PropsWithChildren {}
export default function AuthGuard({ children }: Props): JSX.Element {
const router = useRouter();
const session = useSession({ required: true });
// checks the session each time it changes
useEffect(() => {
if (!session) router.replace("/login");
}, [session]);
return <>{children}</>;
}
export type { Props as AuthGuardProps };
在布局中,您可以简单地导入此组件并用它包装您的内容,但不用担心:用客户端组件包装服务器组件不会导致整个应用程序在客户端上呈现。
import AuthGuard from "@/components/AuthGuard";
import { SessionProvider } from "next-auth/react";
interface Props extends React.PropsWithChildren {}
export default function RootLayout({ children }: Props) {
return (
<html lang="en">
<body className={inter.className}>
<SessionProvider>
<AuthGuard>{children}</AuthGuard>
</SessionProvider>
</body>
</html>
);
}