ChatGPT解决这个技术问题 Extra ChatGPT

如何在 TypeScript 中使用带有 React 无状态功能组件的子组件?

将 TypeScript 与 React 一起使用,我们不再需要扩展 React.Props 以使编译器知道所有 React 组件道具都可以有孩子:

interface MyProps { }

class MyComponent extends React.Component<MyProps, {}> {
  public render(): JSX.Element {
    return <div>{this.props.children}</div>;
  }
}

但是,无状态功能组件似乎并非如此:

const MyStatelessComponent = (props: MyProps) => {
  return (
    <div>{props.children}</div>
  );
};

发出编译错误:

错误:(102, 17) TS2339:“MyProps”类型上不存在属性“children”。

我想这是因为编译器真的无法知道在 props 参数中将给出一个香草函数 children

所以问题是我们应该如何在 TypeScript 的无状态函数组件中使用子组件?

我可以回到 MyProps extends React.Props 的旧方式,但 Props 接口是 marked as deprecated,据我了解,无状态组件没有或不支持 Props.ref

所以我可以手动定义 children 道具:

interface MyProps {
  children?: React.ReactNode;
}

首先:ReactNode 是正确的类型吗?

第二:我必须将孩子写为可选 (?),否则消费者会认为 children 应该是组件 (<MyStatelessComponent children={} />) 的 属性,如果出现错误则会引发错误未提供值。

好像我错过了什么。任何人都可以澄清我的最后一个例子是否是在 React 中使用无状态功能组件和子组件的方法吗?


Y
Yura

您可以为道具使用 React.PropsWithChildren<P> 类型:

interface MyProps { }

function MyComponent(props: React.PropsWithChildren<MyProps>) {
  return <div>{props.children}</div>;
}

p
pztrick

React 16.8 更新: 自 React 16.8 起,名称 React.SFCReact.StatelessComponent 已被弃用。实际上,它们已成为 React.FunctionComponent 类型或简称为 React.FC 的别名。

你会以同样的方式使用它们:

const MyStatelessComponent : React.FunctionComponent<MyProps> = props =>
    <div>
        <p>{props.propInMyProps}</p>
        <p>{props.children}</p>
    </div>

在 React 16.8(旧)之前:

目前,您可以使用 React.StatelessComponent<> 类型,如:

const MyStatelessComponent : React.StatelessComponent<{}> = props =>
    <div>{props.children}</div>

我在那里添加的是将组件的返回类型设置为 React.StatelessComponent 类型。

对于具有您自己的自定义道具(如 MyProps 接口)的组件:

const MyStatelessComponent : React.StatelessComponent<MyProps> = props =>
    <div>
        <p>{props.propInMyProps}</p>
        <p>{props.children}</p>
    </div>

现在,props 已经获得了 children 属性以及来自 MyProps 接口的属性。

我在打字稿版本 2.0.7 中检查了这个

此外,为简洁起见,您可以使用 React.SFC 而不是 React.StatelessComponent


谢谢!看来我使用的是不支持此功能的旧版本类型...我想是时候硬着头皮使用带有 @types 的 TS 2.0
React.StatelessComponent / React.SFC 已弃用。建议参考 React.FunctionComponent
请注意,如果您有通用组件,则此方法不起作用
c
chris6953

更简单的答案:使用 ReactNode

interface MyProps {
  children?: React.ReactNode
}

children 是否可选(即是否有 ?)取决于您的组件。 ? 是表达这一点的最简洁的方式,所以没有错。

关于历史:当最初被问到时,这不一定是正确的答案:类型 ReactNode 仅在 2017 年 3 月以(几乎)当前形式添加by this pull request,但今天几乎每个阅读本文的人都应该 使用足够现代的 React 版本。

最后,关于将 children 作为“属性”传递(在 React 术语中,将其作为“属性”而不是属性传递):这是可能的,但在大多数情况下,在传递 JSX 子节点时会更好读:

<MyComponent>
  <p>This is part of the children.</p>
</MyComponent>

比阅读更容易

<MyComponent children={<p>This is part of the children.</p>} />

N
N S Niko

您可以将子组件添加到组件中,如果它连接到您所需要的容器。

const MyComponent = ({ 
   children  
}) => {
  return <div>{children}</div>

}

这是一个 TypeScript 问题。
J
Jun Yin

您可以使用

interface YourProps { }
const yourComponent: React.SFC<YourProps> = props => {}

React.SFC 已弃用