英文:
Next 13 — client and async server component combined: 'Promise<Element>' is not a valid JSX element
问题
我在实验性的 Next 13 `app` 目录中进行实验。
根据[文档][1],客户端组件可以接受服务器端组件,只要作为 `children` 属性。
它能工作,但是我遇到了类型错误
> ''ServerPage'' 不能用作 JSX 组件。它的返回类型 ''Promise<Element>'' 不是有效的 JSX 元素。
> 类型 ''Promise<Element>'' 缺少类型 ''ReactElement<any, any>'' 的以下属性:type、props、key
import ClientPage from './clientPage';
import ServerPage from './serverPage';
// app/page.tsx
export default function Home() {
// 在服务器中记录日志
console.log('渲染首页');
return (
<>
<ClientPage>
<ServerPage /> // 这里有类型错误
</ClientPage>
</>
);
}
**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 (
<>
<main className={styles.main}>
我是一个服务器组件
</main>
</>
);
}
**clientPage.tsx** 组件
'在客户端使用';
export default function ClientPage({
children,
}: {
children: React.ReactNode;
}) {
// 这在客户端记录日志
console.log('渲染客户端页面');
return (
<>
{children}
</>
);
}
我猜这与 `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 './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.
答案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('next').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<Element>' 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].
> 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<Element>' 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注释
<ClientPage>
// @ts-expect-error 服务器端组件
<ServerPage /> // 这里有类型错误
</ClientPage>
<details>
<summary>英文:</summary>
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>
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论