reactjs 使用异步await的getServerSession时出错

wi3ka0sx  于 2023-05-22  发布在  React
关注(0)|答案(3)|浏览(350)

我尝试在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>
  );
}

Login.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>;
}

但是,这使我的网站成为一个空白页。如果我删除async await和getServerSession(),它可以正常工作。我相信问题出在async await上,但是getServerSession()没有它就不能工作。我正在使用Typescript和应用程序目录。
无法找到为什么我的网站只是去空白,因为异步等待。

qmelpv7a

qmelpv7a1#

  • component* 不能是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>
  );
}
wztqucjr

wztqucjr2#

在我的记忆中,你不能导出一个默认的异步组件。或者你不应该直接使用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希望它能回应你的答案

qltillow

qltillow3#

组件不能是异步函数,它必须是React Functional ComponentReact Class Component
为了解决您遇到的问题,您可以在useEffect中调用async函数,当组件将挂载时:

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>
  );
}

相关问题