使用带有异步等待的 getServerSession 时出错

问题描述 投票:0回答:3

我正在尝试在 next.js 中使用 getServerSession() ,如下所示:

import Login from "./Login";
import Logged from "./Logged";
import { getServerSession } from "next-auth";

export default async function Nav() {
  const session = await getServerSession();
  console.log(session.user);

  return (
    <nav className="flex justify-end">
      {!session?.user && <Login />}
      {session?.user && <Logged />}
    </nav>
  );
}

登录.tsx:

"use client";

import { signIn } from "next-auth/react";

export default function Login() {
  return (
    <nav className="flex justify-end">
      <button
        className="text-black cursor-pointer underline text-lg p-6 hover:text-gray-600"
        onClick={() => signIn()}
      >
        Sign In
      </button>
    </nav>
  );
}

Logged.tsx(尚未添加功能):

export default function Logged() {
  return <button>Sign out</button>;
}

但是,这使我的网站成为空白页面。如果我删除异步等待和 getServerSession(),它工作正常。我相信问题出在异步等待上,但是没有它 getServerSession() 就无法工作。我正在使用 Typescript 和应用程序目录。

找不到为什么我的网站因为异步等待而变成空白。

reactjs next-auth next
3个回答
0
投票

一个组件不能是

async
。如果您想在 React 中异步获取数据,您缺少的核心 React 概念是维护状态。定义一个状态值来存储该数据,在效果中获取数据,并更新状态。

例如:

export default function Nav() {
  const [session, setSession] = useState();

  useEffect(() => {
    const fetchData = async () => {
      const result = await getServerSession();
      setSession(result);
    };
    fetchData();
  }, []);

  console.log(session?.user);

  return (
    <nav className="flex justify-end">
      {!session?.user && <Login />}
      {session?.user && <Logged />}
    </nav>
  );
}

0
投票

据我所知,您无法导出默认的异步组件。或者你不应该直接使用 await getServerSession()。要么使用 getServerSideProps 之类的东西来执行 getServerSession 并发送带有页面道具的信息。或者尝试创建一个包含这样的会话的状态:

export default function Nav() {
  
  const [session, setSession] = useState(null)

  useEffect(()=>{
    const getSession = async () => {
        try{
            const res = await getServerSession();
            if (typeof res === "undefined" || !!!res)
            {
                throw Error("Cannot get server session");
            }
            setSession(res)
        }
        catch (e) 
        {
            console.error(e)
        }

    }
    getSession()
  },[])
  return (
    <nav className="flex justify-end">
      {!session?.user && <Login />}
      {session?.user && <Logged />}
    </nav>
  );
}

next-auth 的文档告诉我们使用 getServerSideProps 如下:

import { authOptions } from 'pages/api/auth/[...nextauth]'
import { getServerSession } from "next-auth/next"
export default YourComponent = (props) => {
// ...your component
}
export async function getServerSideProps(context) {
  const session = await getServerSession(context.req, context.res, authOptions)

  if (!session) {
    return {
      redirect: {
        destination: '/',
        permanent: false,
      },
    }
  }

  return {
    props: {
      session,
    },
  }
}

https://next-auth.js.org/configuration/nextjs 希望它能回应你的回答


0
投票

组件不能是异步函数,它需要是一个

React Functional Component
或一个
React Class Component

为了解决您遇到的问题,您可以在挂载组件时调用

useEffect
中的异步函数:

import Login from "./Login"
import Logged from "./Logged"
import { useEffect, useState } from "react"
import { getServerSession } from "next-auth"

export default function Nav() {
  const [user, setUser] = useState()
  useEffect(() => {
      const fetchAndSet = async () => {
          try {
              const responseData = await getServerSession()
              setUser(responseData.user)
          } catch (error) {
             // Handle your errors in here
         }
     };

      fetchAndSet()
  }, [])

  return (
    <nav className="flex justify-end">
      {user ? <Logged /> : <Login />}
    </nav>
  );
}
© www.soinside.com 2019 - 2024. All rights reserved.