我想在客户端内部使用用户,我使用了useSession。为什么我登录后需要刷新页面才能获取用户信息?
这是我的代码
import NextAuth from "next-auth";
import { PrismaAdapter } from "@auth/prisma-adapter";
import { PrismaClient, UserRole } from "@prisma/client";
import authConfig from "@/auth.config";
import { getUserById } from "@/server/data/user";
const prisma = new PrismaClient();
export const { handlers, signIn, signOut, auth } = NextAuth({
pages: {
error: "/auth/error",
signIn: "/auth/login",
},
adapter: PrismaAdapter(prisma),
secret: process.env.AUTH_SECRET,
session: {
strategy: "jwt",
},
...authConfig,
});
@/auth-config
import type { NextAuthConfig } from "next-auth";
import Credentials from "next-auth/providers/credentials";
import bcrypt from "bcryptjs";
import { LoginSchema } from "@/lib/schemas/user";
import { getUserByEmail } from "@/server/data/user";
export default {
providers: [
Credentials({
async authorize(credentials) {
const validatedFields = LoginSchema.safeParse(credentials);
if (validatedFields.success) {
const { email, password } = validatedFields.data;
const user = await getUserByEmail(email);
if (!user || !user.password) return null;
const passwordMatch = await bcrypt.compare(password, user.password);
if (passwordMatch) return user;
}
return null;
},
}),
],
} satisfies NextAuthConfig;
这是布局
import { Toaster, toast } from "sonner";
import "./globals.css";
import { auth } from "@/auth";
import { SessionProvider } from "next-auth/react";
export default async function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
const session = await auth();
return (
<html lang="fa" dir="rtl" suppressHydrationWarning>
<body className="min-h-screen bg-background font-vazir antialiased">
<SessionProvider session={session}>
{children}
<Toaster className="font-vazir" />
</SessionProvider>
</body>
</html>
);
}
这是我的仪表板页面
"use client";
import LogoutButton from "@/components/shared/auth/logout-button";
import { useSession } from "next-auth/react";
const DashboardPage = () => {
const session = useSession();
console.log(session.data);
return (
<div>
{JSON.stringify(session.data?.user)}
<LogoutButton />
</div>
);
};
export default DashboardPage;
session.data 在控制台中为空只有当我刷新页面时我才得到信息 或者如果您告诉我可以用另一种方法将用户带到客户端,我将不胜感激
我假设布局中的子项在构建期间运行时返回布局中
auth()
的会话数据之前渲染。使用会话的组件虽然是预渲染的(没有会话)。
为了解决这个问题,您可以在布局中使用
getServerSideProps()
(它在请求期间运行),在渲染之前将会话作为道具传递给子级/组件。
(我认为可能还有一种方法可以在会话更改时使用 useEffect 重新渲染子级,但 getServerSideProps 应该是处理此问题的预期方法)
--
供参考:
我什么时候应该使用 getServerSideProps?,Next.js 文档
--
在这一点上,我宁愿不尝试调整布局代码来提供它,因为我是一个菜鸟,并且肯定会在无法测试它的情况下破坏某些东西:D