【问题标题】:How to set default props to required props in functional components?如何将默认道具设置为功能组件中所需的道具?
【发布时间】:2021-07-07 06:18:40
【问题描述】:

在 Typescript 中,我设置了一个组件如下:

interface MyComponentProps {
  type: 'round' | 'square';
}

const MyComponent: FC<MyComponentProps> = ({type = 'round'}) => {
  return (
    <div />
  );
};

type 属性是必需的,并且在组件定义中设置了默认值,但在调用组件时仍然出现错误:

<MyComponent />
// Property 'type' is missing in type '{ }' but required in type 'MyComponentProps'.

将属性type 设置为可选的type? 可以通过将类型隐式更改为'round' | 'square' | undefined 来解决问题,但我不希望该属性可能是undefined,因为这会导致问题和奇怪的代码在我必须考虑type 在每一点上都是undefined 的地方。

我想要发生什么?

我希望 'type' 在未传递时具有默认值,但不定义为 undefined(即可选)。

我尝试了什么?

我尝试添加

MyComponent.defaultProps = {
  type: 'round'
};

但这根本没有帮助,而且我知道 defaultProps 无论如何都将被功能组件弃用。

【问题讨论】:

  • 如果你想要一个默认值,那么这不是必需的属性吗?
  • 技术上是的,但是“非必需”属性表明它是可选的,这意味着它可能是未定义的,我不希望发生这种情况,从那时起我必须断言它在每一步都被定义.
  • 那么默认道具可以正常工作吗?
  • 如果 prop 是可选的并且未传递,则默认 prop 会接管,所以它在这个意义上是有效的。如果 prop 是必需的,有一个默认值,但没有通过,那么应用程序甚至不会编译。定义defaultProps 完全没有效果。
  • 不支持这种方式。当您提供默认道具时。这不是必需的道具。如果您希望该道具作为其他值,则必须传递该值。

标签: reactjs typescript react-props


【解决方案1】:

如果你想传递默认值,这意味着值不是强制性的。如果值不会出现,那么你有默认值。

【讨论】:

    【解决方案2】:

    我建议您尝试以下操作:

    interface MyComponentProps {
      type?: 'round' | 'square';
    }
    
    const defaultProps: MyComponentProps = {
      type: 'round'
    };
    
    const MyComponent: FC<MyComponentProps> = ({type}) => {
      return (
        <div />
      );
    };
    
    MyComponent.defaultProps = defaultProps;
    

    【讨论】:

      【解决方案3】:

      更新typescript@4.4

      由于ts@4.4 设置了exactOptionalPropertyTypes 标志,您可以在没有显式类型断言的情况下定义这样的类型:

      type MyComponentProps = {
        type: 'round' | 'square';
      } | {
        type?: never
      }
      
      const MyComponent = ({type = 'round'}: MyComponentProps) => {
        return (
          <div />
        );
      }
      
      const NoProps = <MyComponent />
      const UndefProp = <MyComponent type={undefined} /> // error
      const WithProp = <MyComponent type="round" />
      

      playground link

      不幸的是,TS 游乐场还不支持在 url 中存储 exactOptionalPropertyTypes 标志。所以你必须进入TS Config并手动设置。


      我相信您无法通过简单的打字稿功能获得您想要的东西。但是使用类型断言稍微按摩你的类型,你可以非常接近:

      interface MyComponentProps {
        type: 'round' | 'square';
      }
      
      const MyComponent = (({type = 'round'}: MyComponentProps) => {
        return (
          <div />
        );
      }) as React.FC<MyComponentProps | {}>
      
      const NoProps = <MyComponent />
      const UndefProp = <MyComponent type={undefined} /> // error
      const WithProp = <MyComponent type="round" />
      

      playground link

      【讨论】:

      • 我不知道这在你的操场上是如何工作的,但是一旦我添加了 | {} 位,我的 IDE 中的所有道具都会丢失它们的类型并省略错误,声称 type 不会t 存在于该界面中。
      • 您能否将带有错误的确切代码复制到 TS 游乐场?
      猜你喜欢
      • 2016-10-26
      • 2019-12-25
      • 2018-05-26
      • 1970-01-01
      • 2017-11-09
      • 2021-08-13
      • 2019-07-14
      • 2016-12-11
      • 2019-11-01
      相关资源
      最近更新 更多