如何在 TypeScript 中使用带有 React Stateless Functional Component 的子组件?

IT技术 reactjs typescript
2021-04-05 17:00:16

将 TypeScript 与 React 一起使用,我们不再需要扩展React.Props以使编译器知道所有 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:“MyProps”类型上不存在“children”属性。

我想这是因为编译器真的没有办法知道将children在 props 参数中给出一个普通函数。

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

我可以回到 的旧方式MyProps extends React.Props,但Props接口被标记为 deprecated,并且无状态组件没有或不支持Props.ref我所理解的a

所以我可以children手动定义props:

interface MyProps {
  children?: React.ReactNode;
}

第一:是ReactNode正确的类型吗?

第二:我必须将 children 写为 optional ( ?) 否则消费者会认为这children应该是组件属性( <MyStatelessComponent children={} />),如果没有提供值,则会引发错误。

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

5个回答

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

interface MyProps { }

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

React 16.8 更新: 自 React 16.8 起,名称React.SFCReact.StatelessComponent已弃用。实际上,它们已成为React.FunctionComponenttype 或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.StatelessComponenttype。

对于具有您自己的自定义props(如MyProps界面)的组件:

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

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

我在typescript版本 2.0.7 中检查了这个

此外,为了简洁起见,您可以使用React.SFC代替React.StatelessComponent

谢谢!似乎我使用的是不支持此功能的旧版本打字机...我想是时候咬紧牙关使用 TS 2.0 了@types
2021-05-22 17:00:16
React.StatelessComponent/React.SFC已弃用。建议改为参考React.FunctionComponent
2021-05-22 17:00:16
请注意,如果您有通用组件,则此方法不起作用
2021-06-06 17:00:16

更简单的答案:使用ReactNode

interface MyProps {
  children?: React.ReactNode
}

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

关于历史:当最初被问到时,这不一定是正确的答案:该类型ReactNode是在 2017 年 3 月通过此拉取请求以(几乎)当前形式添加的,但几乎今天阅读本文的每个人都应该使用足够现代的 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>} />

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

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

}
这是一个 TypeScript 问题。
2021-05-22 17:00:16

您可以使用

interface YourProps { }
const yourComponent: React.SFC<YourProps> = props => {}
React.SFC 已弃用
2021-05-30 17:00:16