如何在 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 接口被 标记为 deprecated ,并且无状态组件没有或不支持 Props.ref 我明白了。

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

 interface MyProps {
  children?: React.ReactNode;
}

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

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

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

原文由 Aaron Beall 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 678
2 个回答

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

原文由 Leone 发布,翻译遵循 CC BY-SA 4.0 许可协议

您可以使用 React.PropsWithChildren<P> 为您的道具输入:

 interface MyProps { }

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

原文由 Yura 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进