You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js中使用NextAuth凭证登录时Session Provider导致页面渲染报错

Next.js中使用NextAuth凭证登录时Session Provider导致页面渲染报错

Hey Ahmed,我看了你的代码和报错信息,问题其实不在Session Provider本身,而是你把MyApp组件定义成了异步函数!React组件不能是async函数,因为异步函数会返回一个Promise对象,而React期望渲染的是React元素(或null/字符串等合法的React子节点),这就是你看到"Objects are not valid as a React child (found: [object Promise])"的核心原因。

我猜你可能是之前尝试在_app里获取服务器session时,顺手加上了async关键字,但这个写法完全不符合React组件的要求,咱们一步步来解决:

第一步:修复组件的异步问题

直接把MyApp的async关键字去掉,React组件必须是同步函数:

// 把 async function MyApp(...) 改成下面这样
function MyApp({ Component, pageProps }: AppPropsWithLayout) {
  // 你原来的状态、方法、useEffect逻辑都保留,不需要改动
  const [currentToast, setCurrentToast] = useState<
    null | any | ToastNottficationtype[]
  >(null);
  // ... 其他原有代码
}

第二步:正确传递Session给SessionProvider

如果你需要在全局使用服务器端获取的session,不能在MyApp组件内部异步获取,而是通过以下两种方式:

方式1:页面级单独获取(推荐)

在需要session的页面中,用getServerSideProps异步获取session,再通过pageProps传递:

// 比如你的登录页面或首页代码
import { getServerSession } from "next-auth/next";
import { authOptions } from "../path/to/your/auth/options"; // 你的NextAuth配置

export async function getServerSideProps(context) {
  const session = await getServerSession(context.req, context.res, authOptions);
  return {
    props: { session }, // 把session传给页面的props
  };
}

这样MyApp里的pageProps.session就是已经解析好的session对象,直接传给SessionProvider就行。

方式2:全局_app中统一获取

如果要在全局所有页面都注入session,可以给MyApp添加getInitialProps方法:

import App from "next/app";
import { getServerSession } from "next-auth/next";
import { authOptions } from "../path/to/your/auth/options";

MyApp.getInitialProps = async (appContext) => {
  // 先获取默认的appProps
  const appProps = await App.getInitialProps(appContext);
  // 从服务器端获取session
  const session = await getServerSession(appContext.ctx.req, appContext.ctx.res, authOptions);
  // 把session合并到pageProps中
  return { ...appProps, pageProps: { ...appProps.pageProps, session } };
};

额外优化建议

你的Toast状态类型定义有点混乱,建议统一成ToastNottficationtype[],避免any和空值判断的麻烦:

// 初始化空数组,而不是null
const [currentToast, setCurrentToast] = useState<ToastNottficationtype[]>([]);

// 修改提示方法,用函数式更新更安全
const showSuccessToast = (title: string) => {
  setCurrentToast(prev => [...prev, { massgesKey: title, type: "success" }]);
};

const showErrorToast = (title: string) => {
  setCurrentToast(prev => [...prev, { massgesKey: title, type: "error" }]);
};

// 渲染时也不需要复杂的空值判断
{currentToast.length > 0 &&
  currentToast.map((notification: ToastNottficationtype, index: number) => (
    <ToastNottfication
      key={index}
      massgesKey={notification.massgesKey}
      type={notification.type}
    />
  ))
}

备注:内容来源于stack exchange,提问作者Ahmed ibrahim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 11:23:02