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

Header无法作为JSX组件使用:返回类型Promise不是有效JSX元素

问题:Header组件无法作为JSX使用,返回Promise而非有效JSX元素

报错信息:Header cannot be used as a JSX component. Its return type 'Promise' is not a valid JSX element. Type 'Promise' is missing the following properties from type 'ReactElement<any, any>': type, props, key

原代码实现

import Image from "next/image";
import Link from "next/link";
import LogoutButton from "./LogoutButton";
import { unstable_getServerSession } from "next-auth/next";

async function Header() {
  const session = await unstable_getServerSession();

  if (session)
    return (
      <header className="sticky top-0 z-50 bg-white flex justify-between items-center p-10 shadow-sm">
        <div className="flex space-x-2">
          <Image
            className="rounded-full mx-2 object-contain"
            height={10}
            width={50}
            src={session.user?.image!}
            alt="Profile Picture"
          />
          <div>
            <p className="text-blue-400">Logged in as:</p>
            <p className="font-bold text-lg">{session.user?.name}</p>
          </div>
        </div>

        <LogoutButton />
      </header>
    );

  return (
    <header className="sticky top-0 z-50 bg-white flex justify-center items-center p-10 shadow-sm">
      <div className="flex flex-col items-center space-y-5">
        <div className="flex space-x-2 items-center">
          <Image
            src="https://links.papareact.com/jne"
            height={10}
            width={50}
            alt="Logo"
          />
          <p className="text-blue-400">Welcome to Meta Messenger</p>
        </div>
        <Link
          href="/auth/signin"
          className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
        >
          Sign In
        </Link>
      </div>
    </header>
  );
}

export default Header;

问题原因

React(Next.js Pages Router)不支持将async函数作为组件使用,因为async函数的返回值是Promise,而JSX组件要求返回ReactElement类型的结果,两者类型不匹配导致报错。

解决方法

方法1:在页面的getServerSideProps中获取session,传入Header组件

在使用Header的页面组件中,通过getServerSideProps获取session,再作为props传递给Header:

// 页面组件(比如pages/index.js)
import Header from '../components/Header';
import { unstable_getServerSession } from "next-auth/next";
import { authOptions } from "../pages/api/auth/[...nextauth]"; // 引入你的auth配置

export async function getServerSideProps(context) {
  const session = await unstable_getServerSession(context.req, context.res, authOptions);
  return { props: { session } };
}

export default function Home({ session }) {
  return (
    <>
      <Header session={session} />
      {/* 页面其他内容 */}
    </>
  );
}

修改Header组件,去掉async逻辑,直接接收props中的session:

// Header组件
import Image from "next/image";
import Link from "next/link";
import LogoutButton from "./LogoutButton";

function Header({ session }) {
  if (session)
    return (
      <header className="sticky top-0 z-50 bg-white flex justify-between items-center p-10 shadow-sm">
        <div className="flex space-x-2">
          <Image
            className="rounded-full mx-2 object-contain"
            height={10}
            width={50}
            src={session.user?.image!}
            alt="Profile Picture"
          />
          <div>
            <p className="text-blue-400">Logged in as:</p>
            <p className="font-bold text-lg">{session.user?.name}</p>
          </div>
        </div>

        <LogoutButton />
      </header>
    );

  return (
    <header className="sticky top-0 z-50 bg-white flex justify-center items-center p-10 shadow-sm">
      <div className="flex flex-col items-center space-y-5">
        <div className="flex space-x-2 items-center">
          <Image
            src="https://links.papareact.com/jne"
            height={10}
            width={50}
            alt="Logo"
          />
          <p className="text-blue-400">Welcome to Meta Messenger</p>
        </div>
        <Link
          href="/auth/signin"
          className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
        >
          Sign In
        </Link>
      </div>
    </header>
  );
}

export default Header;

方法2:使用客户端数据获取工具(如SWR)在Header内部获取session

如果不想在页面层传递props,可以用SWR在客户端获取session:

首先安装SWR:

npm install swr
# 或
yarn add swr

修改Header组件:

import Image from "next/image";
import Link from "next/link";
import LogoutButton from "./LogoutButton";
import useSWR from 'swr';

// 定义获取session的函数
const fetcher = async () => {
  const res = await fetch('/api/auth/session');
  const data = await res.json();
  return data;
};

function Header() {
  const { data: session } = useSWR('/api/auth/session', fetcher);

  // 可选:处理加载状态
  if (session === undefined) {
    return <header className="sticky top-0 z-50 bg-white p-10 shadow-sm">Loading...</header>;
  }

  if (session)
    return (
      <header className="sticky top-0 z-50 bg-white flex justify-between items-center p-10 shadow-sm">
        <div className="flex space-x-2">
          <Image
            className="rounded-full mx-2 object-contain"
            height={10}
            width={50}
            src={session.user?.image!}
            alt="Profile Picture"
          />
          <div>
            <p className="text-blue-400">Logged in as:</p>
            <p className="font-bold text-lg">{session.user?.name}</p>
          </div>
        </div>

        <LogoutButton />
      </header>
    );

  return (
    <header className="sticky top-0 z-50 bg-white flex justify-center items-center p-10 shadow-sm">
      <div className="flex flex-col items-center space-y-5">
        <div className="flex space-x-2 items-center">
          <Image
            src="https://links.papareact.com/jne"
            height={10}
            width={50}
            alt="Logo"
          />
          <p className="text-blue-400">Welcome to Meta Messenger</p>
        </div>
        <Link
          href="/auth/signin"
          className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
        >
          Sign In
        </Link>
      </div>
    </header>
  );
}

export default Header;

方法3:如果使用Next.js 13+ App Router,将Header改为Server Component

如果你的项目用的是App Router(目录结构为app/),可以直接保留async组件,因为App Router默认支持Server Component(无需额外配置,只要组件未使用客户端钩子如useState、useEffect即可):

// app/components/Header.jsx
import Image from "next/image";
import Link from "next/link";
import LogoutButton from "./LogoutButton";
import { unstable_getServerSession } from "next-auth/next";
import { authOptions } from "../api/auth/[...nextauth]/route"; // 对应App Router的auth配置路径

async function Header() {
  const session = await unstable_getServerSession(authOptions);

  if (session)
    return (
      <header className="sticky top-0 z-50 bg-white flex justify-between items-center p-10 shadow-sm">
        <div className="flex space-x-2">
          <Image
            className="rounded-full mx-2 object-contain"
            height={10}
            width={50}
            src={session.user?.image!}
            alt="Profile Picture"
          />
          <div>
            <p className="text-blue-400">Logged in as:</p>
            <p className="font-bold text-lg">{session.user?.name}</p>
          </div>
        </div>

        <LogoutButton />
      </header>
    );

  return (
    <header className="sticky top-0 z-50 bg-white flex justify-center items-center p-10 shadow-sm">
      <div className="flex flex-col items-center space-y-5">
        <div className="flex space-x-2 items-center">
          <Image
            src="https://links.papareact.com/jne"
            height={10}
            width={50}
            alt="Logo"
          />
          <p className="text-blue-400">Welcome to Meta Messenger</p>
        </div>
        <Link
          href="/auth/signin"
          className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
        >
          Sign In
        </Link>
      </div>
    </header>
  );
}

export default Header;

内容的提问来源于stack exchange,提问作者anasryadi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 07:45:24