‘Promise<Element>’ 不是有效的JSX元素

huangapple go评论70阅读模式
英文:

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

问题

我在实验性的 Next 13 `app` 目录中进行实验。

根据[文档][1],客户端组件可以接受服务器端组件,只要作为 `children` 属性。

它能工作,但是我遇到了类型错误

&gt; '&#39;ServerPage&#39;' 不能用作 JSX 组件。它的返回类型 '&#39;Promise&lt;Element&gt;&#39;' 不是有效的 JSX 元素。
&gt;     类型 '&#39;Promise&lt;Element&gt;&#39;' 缺少类型 '&#39;ReactElement&lt;any, any&gt;&#39;' 的以下属性:type、props、key

    import ClientPage from './clientPage';
    import ServerPage from './serverPage';
    
    // app/page.tsx
    export default function Home() {
      // 在服务器中记录日志
      console.log('渲染首页');
    
      return (
        &lt;&gt;
          &lt;ClientPage&gt;
            &lt;ServerPage /&gt; // 这里有类型错误
          &lt;/ClientPage&gt;
        &lt;/&gt;
      );
    }

**serverPage.tsx** 组件

    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();
      // 这在服务器中记录日志
      console.log(data);
    
      return (
        &lt;&gt;
          &lt;main className={styles.main}&gt;
            我是一个服务器组件
          &lt;/main&gt;
        &lt;/&gt;
      );
    }

**clientPage.tsx** 组件

    '在客户端使用';
    
    export default function ClientPage({
      children,
    }: {
      children: React.ReactNode;
    }) {
      // 这在客户端记录日志
      console.log('渲染客户端页面');
      return (
        &lt;&gt;
          {children}
        &lt;/&gt;
      );
    }

我猜这与 `clientPage` 组件中的 children 类型有关,但我不确定应该如何对其进行类型化。

  [1]: https://beta.nextjs.org/docs/rendering/server-and-client-components#importing-server-components-into-client-components
英文:

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<Element>' is not a valid JSX element.
> Type 'Promise<Element>' is missing the following properties from type 'ReactElement<any, any>': type, props, key

import ClientPage from &#39;./clientPage&#39;;
import ServerPage from &#39;./serverPage&#39;;

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

  return (
    &lt;&gt;
      &lt;ClientPage&gt;
        &lt;ServerPage /&gt; // type error here
      &lt;/ClientPage&gt;
    &lt;/&gt;
  );
}

the serverPage.tsx component

const fetchSomeData = async () =&gt; {
  const response = await fetch(&#39;https://pokeapi.co/api/v2/pokemon/ditto&#39;);

  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 (
    &lt;&gt;
      &lt;main className={styles.main}&gt;
        Im a server component
      &lt;/main&gt;
    &lt;/&gt;
  );
}

the clientPage.tsx component

&#39;use client&#39;;

export default function ClientPage({
  children,
}: {
  children: React.ReactNode;
}) {
  // this logs in the client
  console.log(&#39;rendering client page&#39;);
  return (
    &lt;&gt;
      {children}
    &lt;/&gt;
  );
}

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.

答案1

得分: 4

Async Server Component TypeScript Error

要使用 TypeScript 来创建异步服务器组件,请确保你的 TypeScript 版本高于 5.1.3,同时使用 @types/react 版本高于 18.2.8。

如果你使用的 TypeScript 版本较旧,可能会出现 "'Promise<Element>'" 不是有效的 JSX 元素类型错误。更新到最新版本的 TypeScript 和 @types/react 应该解决此问题。

next.config.js

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

module.exports = nextConfig;
英文:

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<Element>' 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(&#39;next&#39;).NextConfig} */
const nextConfig = {
  experimental: { serverActions: true },
};

module.exports = nextConfig;

``

</details>



# 答案2
**得分**: 1

抱歉代码部分不需要翻译以下是已翻译的内容

"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][1].

> 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&lt;Element&gt;' is not a valid JSX element. We are tracking [this issue here][2].

[1]: https://beta.nextjs.org/docs/configuring/typescript
[2]: https://github.com/vercel/next.js/issues/42292"

<details>
<summary>英文:</summary>

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][1].

&gt; 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 &#39;Promise&lt;Element&gt;&#39; is not a valid JSX element. We are tracking [this issue here][2].


  [1]: https://beta.nextjs.org/docs/configuring/typescript
  [2]: https://github.com/vercel/next.js/issues/42292

</details>



# 答案3
**得分**: 0

这是一个错误Next.js团队已经在处理你也可以使用eslint注释

      &lt;ClientPage&gt;
        // @ts-expect-error 服务器端组件
        &lt;ServerPage /&gt; // 这里有类型错误
      &lt;/ClientPage&gt;

<details>
<summary>英文:</summary>

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

      &lt;ClientPage&gt;
        // @ts-expect-error Server Component
        &lt;ServerPage /&gt; // type error here
      &lt;/ClientPage&gt;

</details>



huangapple
  • 本文由 发表于 2023年2月19日 09:25:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/75497449.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定