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

Aar*_*all 36 typescript reactjs

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

interface MyProps { }

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

但是,无状态功能组件似乎不是这样的:

const MyStatelessComponent = (props: MyProps) => {
  return (
    <div>{props.children}</div>
  );
};
Run Code Online (Sandbox Code Playgroud)

发出编译错误:

错误:(102,17)TS2339:"MyProps"类型中不存在属性"children".

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

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

我可以回到以前的方式MyProps extends React.Props,但Props界面被标记为已弃用,无状态组件没有或支持Props.ref我理解它.

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

interface MyProps {
  children?: React.ReactNode;
}
Run Code Online (Sandbox Code Playgroud)

第一:是ReactNode正确的类型?

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

好像我错过了一些东西.任何人都可以清楚地说明我的最后一个例子是否是在React中使用无子功能组件和子项的方法?

Leo*_*one 43

目前,您可以使用以下React.SFC类型:

const MyStatelessComponent : React.FunctionComponent<MyProps> = props =>
    <div>
        <p>{props.propInMyProps}</p>
        <p>{props.children}</p>
    </div>
Run Code Online (Sandbox Code Playgroud)

我在那里添加的是设置要键入的组件的返回React.StatelessComponent类型.

对于具有您自己的自定义道具(如React.FunctionComponent界面)的组件:

const MyStatelessComponent : React.StatelessComponent<{}> = props =>
    <div>{props.children}</div>
Run Code Online (Sandbox Code Playgroud)

现在,React.FC已经获得了React.StatelessComponent<>属性以及来自React.StatelessComponent界面的属性.

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

此外,您可以使用MyProps而不是props为了简洁.

  • `React.StatelessComponent` / `React.SFC` 已弃用。建议改为参考 `React.FunctionComponent`。 (3认同)

bai*_*tun 20

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

interface MyProps { }

function MyComponent(props: React.PropsWithChildren<MyProps>) {
  return <div>{props.children}</div>;
}
Run Code Online (Sandbox Code Playgroud)

  • 我认为这个答案目前可能被认为是正确的答案。由于 [React Typescript Cheatsheet](https://react-typescript-cheatsheet.netlify.app/docs/basic/getting-started/function_components) 中不鼓励使用“React.FunctionComponent”(或简写 React.FC)。 (2认同)

chr*_*953 17

更简单的答案:使用ReactNode

interface MyProps {
  children?: React.ReactNode
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

<MyComponent>
  <p>This is part of the children.</p>
</MyComponent>
Run Code Online (Sandbox Code Playgroud)

比阅读更容易

<MyComponent children={<p>This is part of the children.</p>} />
Run Code Online (Sandbox Code Playgroud)