我正在尝试将一些用较旧版本(我认为是14或16)编写的ReactJS代码转换为18,并且该代码多次使用props.children,这在较新版本的ReactJS中已被删除。我找到了很多解决此问题的教程,但我只能找到引用功能组件的教程,而不是引用类的教程。
export class SystemStatusContainer extends React.Component<
{},
{
status: systemStatuses;
pollStatus: boolean;
}
> {
state = {
status: systemStatuses.online,
pollStatus: true,
};
timer: NodeJS.Timeout;
.
.
.
render() {
const { status } = this.state;
if (status === systemStatuses.offline) {
return <SystemUnavailableModal />;
} else if (status === systemStatuses.update) {
return <SystemStatusModal />;
} else {
return this.props.children;
}
}
如何将底线 this.props.children 转换为在 ReactJS 18 中工作?我在网上找到的所有方法都涉及将子级直接传递到组件中,但这仅在它是功能组件而不是类时才有效(据我所知)。
注意: 这段代码不是我的,因此,我试图尽可能减少更改。如果代码中存在与本问题无关的问题,请不要提出,除非它们会直接影响 this.props.children 的问题。
您的代码完全可以在运行时运行。这只是一个打字稿错误。
React 没有删除
this.props.children
,但是前面的代码有错误,因为 React.Component
的第一个参数是 props 的类型。在那里,你没有定义任何道具,甚至没有定义孩子。所以打字稿编译器会警告你:Property 'children' does not exist on type 'Readonly<{}>'.ts(2339)
如果正确定义类型,错误就会消失。
export class SystemStatusContainer extends React.Component<
{ children: React.ReactNode },
...
看看这个游乐场。
您可以将子项指定为命名道具或在标签内:
<SystemStatusContainer> This is children </SystemStatusContainer>
<SystemStatusContainer children="This is children too!" />
从 React 17 到 React 18 的变化是类型。在 React 17 中,类型 Component 确实在 props 中包含了子元素。
class Component {
...
readonly props: Readonly<P> & Readonly<{ children?: ReactNode | undefined }>;
}
在 React 18 的类型中,props 只是一个只读对象:
class Component {
...
readonly props: Readonly<P>;
}
React 18 中的更改是默认从 props 的
type中删除
children
(在 Component
和功能组件可选使用的 React.FunctionComponent
[aka React.FC
] 类型中)。它被删除是因为并非所有组件都应该有子组件(考虑一个最终只渲染像 <input />
这样的 void 元素的组件)。
如果您的组件有子组件,它将有一个包含这些子组件的
children
属性。所以我们要做的就是确保组件的 props 类型符合这一点。
要使该代码再次工作,请在 props 类型中声明
children
(Component
的第一个类型参数)。 React 提供了一个实用程序类型 PropsWithChildren
,它将把 children
添加到 props 类型中。 React 定义 PropsWithChildren
如下:
export type PropsWithChildren<P = unknown> = P & {
children?: ReactNode | undefined;
};
所以我们将它用在你的空 props 对象类型上:
export class SystemStatusContainer extends React.Component<
PropsWithChildren<{}>, // <=======================
{
status: systemStatuses;
pollStatus: boolean;
}
> {
state = {
status: systemStatuses.online,
pollStatus: true,
};
// ...
这是一个非常基本的示例(在 TypeScript 游乐场上):
import { Component, PropsWithChildren } from "react";
class Example extends Component<PropsWithChildren<{}>, {}> {
render() {
return this.props.children;
}
}