Next.js 13和下一个授权的问题与usessession和SessionProvider &g



我正在尝试制作一个登录页面。在我的页面上。根据是否包含"use client";在我代码的顶端。如果我没有"使用客户端"我得到这个错误:Error: React Context is unavailable in Server Components如果我使用了"使用客户端"我得到这个错误:Error: [next-auth]:usessessionmust be wrapped in a <SessionProvider />

这是我的布局。tsx文件:

import Image from 'next/image'
import { SessionProvider } from "next-auth/react";
import { ReactNode } from "react";
import React from 'react';
import "./globals.css";
import Link from "next/link";
type Props = {
children: ReactNode;
session: any;
};
export default function Layout({ children, session }: Props) {
return (
<html lang="en">
<head />
<body>
<div className="mx-auto">
<div className="flex flex-row flex-wrap">
<aside className="w-full sm:w-1/3 md:w-1/5 xl:w-1/6 border-r-2 border-[#F845C6]">
<div className="sticky top-0 p-4 w-full">
<ul className="flex flex-col overflow-hidden">
<li className="m-5 text-center">
<Link href="login">LOGO</Link>
</li>
<li className="m-5 text-center">
<Link href="/">Dashboard</Link>
</li>
<li className="m-5 text-center">
<Link href="tasks">Tasks</Link>
</li>
<li className="m-5 text-center">
<Link href="reporting">Reporting</Link>
</li>
</ul>
</div>
</aside>
<div className="w-full sm:w-2/3 md:w-4/5 xl:w-5/6">{children}</div>
</div>
</div>
</body>
</html>
);
}
export function getLayout(page: any) {
const { session } = page.props;
return (
<SessionProvider session={session}>
<Layout session={session}>{page}</Layout>
</SessionProvider>
);
}

这是登录页面。tsx文件:

"use client";
import React from 'react'
import { useSession, signIn, signOut } from 'next-auth/react'
import { getLayout } from '../components/Layout'
export default function Login() {
const { data: session } = useSession();
console.log(session);
if (session) {
return (
<div style={{ fontFamily: 'sans-serif', margin: '10px 20px' }}>
<p>Welcome, {session.user.name}</p>
<img src={session.user.image} alt="" style={{ borderRadius: '15px', width: '80px', margin: '10px' }} />
<button onClick={() => signOut()}>Sign out</button>
</div>
);
} else {
return (
<div>
<p>Please sign in</p>
<button onClick={() => signIn("google", { callbackUrl: '/account' })}>Sign in with Google</button>
</div>
);
}
}
Login.getLayout = function getLayout(page: any) {
return getLayout(page);
};

我试图从一个旧的项目移动到一个使用应用程序目录。我试图添加的SessionProvider代码是在原来的_app.js文件的根布局,但我没有任何运气

对于遇到此页面的任何人,如果您从未解决过这个问题,SessionProvider只需要包装在服务器渲染布局中使用的客户端组件中,而不是直接应用于布局中。

创建一个提供商文件:

"use client";
import { SessionProvider } from "next-auth/react";
type Props = {
children?: React.ReactNode;
};
export const NextAuthProvider = ({ children }: Props) => {
return <SessionProvider>{children}</SessionProvider>;
};

,然后在你的根布局中使用它,像这样:

type Props = {
children: ReactNode;
};
export default function RootLayout({ children }: Props) {
...
return (
...
<NextAuthProvider>
...
{children}
...
</NextAuthProvider>
...
);
}

这将使您能够访问整个站点中所有客户端组件中的会话上下文,这通常是您想要的。

你可以用两行代码从客户端组件重新导出你的SessionProvider:

"use client";
export { SessionProvider } from "next-auth/react";

这也适用于你想要变成客户端组件的其他第三方组件。