reactjs - Next-auth: getServerSideProps から渡されたのにページにプロップが未定義
私は、next-authを使用してgetSessionから取得したセッションをページのプロパティとして渡そうとしています。コンポーネント内でuseSession()を使うことはできると知っていますが、私の理解ではこれも動作するはずで、なぜ動作しないのか理解できません。
これはこの質問と同じような問題のようですが、答えはありません。
こちらが私の非常に基本的なpages/settings.tsxです:
import { Card, CardContent, Typography } from "@mui/material";
import { User } from "@prisma/client";
import { GetServerSideProps, NextPage } from "next";
import { getSession } from "next-auth/react";
interface SettingsProps {
user: User,
}
const Settings : NextPage<SettingsProps> = ({user})=>{
// in here, user is always undefined...
return (
<Card>
<CardContent>
<Typography variant="h3">Settings</Typography>
<Typography>UserId: {user.id}</Typography>
<Typography>Created: {(new Date(user.createdAt)).toLocaleDateString()}</Typography>
</CardContent>
</Card>
);
};
export const getServerSideProps: GetServerSideProps<SettingsProps> = async (context) =>{
const session = await getSession(context);
if (!session) {
return {
redirect: {
destination: '/',
permanent: false,
},
};
}
console.log(session.user); // this works and logs the user
return {
props: { user: session.user },
};
};
export default Settings;
次のようにして next-auth の Session 型を拡張しました(types/next-auth.d.ts):
import { User } from "@prisma/client";
import NextAuth from "next-auth";
declare module "next-auth" {
/**
* Returned by `useSession`, `getSession` and received as a prop on the `SessionProvider` React Context
*/
interface Session {
user: User
}
}
私のReactとNextJsの理解によれば、上記のコードは問題なく動作するはずですが、ページを訪れると
TypeError: Cannot read properties of undefined (reading 'id')
13 | <CardContent>
14 | <Typography variant="h3">Settings</Typography>
> 15 | <Typography>UserId: {user.id}</Typography>
| ^
16 | <Typography>Created: {(new Date(user.createdAt)).toLocaleDateString()}</Typography>
17 | </CardContent>
18 |
私は何を間違っているのですか?
回答 #1
私は同じ問題に直面していて、純粋な運でそれを解決しました。
どうやら Next.js は、その pageProps を通じて、ページ内で session プロップを利用しているようです。ですので、getServerSideProps から直接 session を渡そうとすると、なぜかクライアントコンポーネントでは未定義になっています。
要するに、sessionからユーザーを返すか、セッション変数の名前を別のものに変更してください。
これは、SSR認証保護が必要な場所すべてでアプリ全体で使用しているパターンです:
export const getServerSideProps: GetServerSideProps = async ({ req, res }) => {
const session = await unstable_getServerSession(req, res, authOptions);
const user = session?.user;
if (!user) {
return {
redirect: {
destination: "/",
permanent: false,
},
};
}
return {
props: {
user,
},
};
};
回答 #2
セッションにユーザーオブジェクトがあり、ユーザーオブジェクトにIDがある場合は、先に述べたように、私にはすべて問題なさそうです。ですので、オプションの変更を使用することができます。
<Typography variant="h3">Settings</Typography>
<Typography>UserId: {user?.id}</Typography>
