Fer Toasted
Fer Toasted

Reputation: 1738

Next 13 — client and async server component combined: 'Promise<Element>' is not a valid JSX element

I was playing with the experimental Next 13 app directory.

As per the documents, a client component can accept a server component, as long as it is as a children prop.

It works, however I do get a type error

'ServerPage' 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 ClientPage from './clientPage';
import ServerPage from './serverPage';

// app/page.tsx
export default function Home() {
  // logs in the server
  console.log('rendering home page');

  return (
    <>
      <ClientPage>
        <ServerPage /> // type error here
      </ClientPage>
    </>
  );
}

the serverPage.tsx component

const fetchSomeData = async () => {
  const response = await fetch('https://pokeapi.co/api/v2/pokemon/ditto');

  if (!response.ok) {
    throw new Error(response.statusText);
  }

  return response.json();
};

export default async function ServerPage() {
  const data = await fetchSomeData();
  // this logs in the server
  console.log(data);

  return (
    <>
      <main className={styles.main}>
        Im a server component
      </main>
    </>
  );
}

the clientPage.tsx component

'use client';

export default function ClientPage({
  children,
}: {
  children: React.ReactNode;
}) {
  // this logs in the client
  console.log('rendering client page');
  return (
    <>
      {children}
    </>
  );
}

I suppose that this has to do with the children type in the clientPage component, but I'm not sure how this should be typed.

Upvotes: 7

Views: 9065

Answers (3)

Chukwuemeka Maduekwe
Chukwuemeka Maduekwe

Reputation: 8566

Async Server Component TypeScript Error

To use an async Server Component with TypeScript, ensure you are using TypeScript 5.1.3 or higher and @types/react 18.2.8 or higher.

If you are using an older version of TypeScript, you may see a 'Promise' is not a valid JSX element type error. Updating to the latest version of TypeScript and @types/react should resolve this issue.

next.config.js

/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: { serverActions: true },
};

module.exports = nextConfig;

``

Upvotes: 6

Yilmaz
Yilmaz

Reputation: 49661

This is a bug. Next.js team has been working on it. You could also use eslint comment

  <ClientPage>
    // @ts-expect-error Server Component
    <ServerPage /> // type error here
  </ClientPage>

Upvotes: 0

Wesley LeMahieu
Wesley LeMahieu

Reputation: 2613

Unfortunately, the only way around this at the moment is to use the :any type definition on the async server components. Next.js 13 outlined this in their Typescript documentation.

Warning: You can use async/await in layouts and pages, which are Server Components. Using async/await inside other components, with TypeScript, can cause errors from the response type from JSX. You might see the error 'Promise' is not a valid JSX element. We are tracking this issue here.

Upvotes: 2

Related Questions