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

时间:2016-11-22 17:46:23

标签: reactjs typescript

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

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:属性'children'在类型上不存在   'MyProps'。

我想这是因为编译器真的没办法知道在props参数中会给出一个vanilla函数children

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

我可以回到MyProps extends React.Props的旧方式,但Props界面为marked as deprecated,无状态组件没有或支持Props.ref,因为我明白它。

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

interface MyProps {
  children?: React.ReactNode;
}

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

第二:我必须将子项写为可选项(?),否则消费者会认为children应该是组件的属性({{1如果没有提供值,则引发错误。

好像我错过了什么。任何人都可以清楚地说明我的最后一个例子是否是在React中使用无子函数组件和子项的方法吗?

5 个答案:

答案 0 :(得分:31)

目前,您可以使用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

<强>更新 自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>

答案 1 :(得分:1)

您可以将React.PropsWithChildren<P>类型用于道具:

interface MyProps { }

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

答案 2 :(得分:0)

您可以使用

.componentClass

答案 3 :(得分:0)

简单的答案:使用ReactNode

interface MyProps {
  children?: React.ReactNode
}

children是否可选(即是否具有?)取决于您的组件。 ?是最简洁的表达方式,因此没有错。

关于历史记录:最初询问时,这不一定是正确的答案:ReactNode类型(几乎)是在2017年3月才以当前形式添加的by this pull request,但是今天几乎所有人都在阅读应该放在足够现代的React版本上。

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

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

阅读比

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

答案 4 :(得分:0)

您只需将子代添加到组件中,并且只要将其连接到您所需要的容器即可。

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

}