当前位置: 首页 > 面试题库 >

使用TypeScript在React组件中的默认属性值

崔琦
2023-03-14
问题内容

我不知道如何使用Typescript为我的组件设置默认属性值。

这是源代码:

class PageState
{
}

export class PageProps
{
    foo: string = "bar";
}

export class PageComponent extends React.Component<PageProps, PageState>
{
    public render(): JSX.Element
    {
        return (
            <span>Hello, world</span>
        );
    }
}

当我尝试使用这样的组件时:

ReactDOM.render(<PageComponent />, document.getElementById("page"));

我收到一条错误消息,指出foo缺少属性。我想使用默认值。我也尝试过static defaultProps = ...在组件内部使用,但是我怀疑它没有任何作用。

src/typescript/main.tsx(8,17): error TS2324: Property 'foo' is missing in type 'IntrinsicAttributes & IntrinsicClassAttributes<PageComponent> & PageProps & { children?: ReactEle...'.

如何使用默认属性值?我公司使用的许多JS组件都依赖于它们,不使用它们不是一种选择。


问题答案:

带类组件的默认道具

使用static defaultProps是正确的。您还应该使用接口(而不是类)作为道具和状态。

更新2018/12/1
:TypeScriptdefaultProps随着时间的推移改进了与类型相关的类型检查。继续阅读以获取最新和最佳用法,直至较旧的用法和问题。

对于TypeScript 3.0及更高版本

TypeScript特别添加了defaultProps对使类型检查按预期工作的支持。例:

interface PageProps {
  foo: string;
  bar: string;
}

export class PageComponent extends React.Component<PageProps, {}> {
    public static defaultProps = {
        foo: "default"
    };

    public render(): JSX.Element {
        return (
            <span>Hello, { this.props.foo.toUpperCase() }</span>
        );
    }
}

可以在不传递foo属性的情况下进行渲染和编译:

<PageComponent bar={ "hello" } />

注意:

  • foo即使不是JSX属性所必需的,也 标记为可选(即foo?: string)。标记为可选意味着它可以是undefined,但是实际上永远不会,undefined因为defaultProps它提供了默认值。可以将其视为类似于如何将函数参数标记为可选,或将其标记为默认值,但不能同时标记为两者,但这两者都意味着调用不需要指定value。TypeScript 3.0+的处理defaultProps方式相似,这对React用户来说真的很酷!
  • defaultProps没有明确的类型注释。推断出它的类型,并由编译器使用它来确定需要哪些JSX属性。您可以使用defaultProps: Pick<PageProps, "foo">确保defaultProps匹配的子集PageProps。有关此警告的更多信息,请在此处说明。
  • 这需要@types/react版本16.4.11才能正常工作。

对于TypeScript 2.1直到3.0

在TypeScript
3.0实施对defaultProps您的编译器支持之前,您仍然可以使用它,并且它在运行时可与React一起使用100%,但是由于TypeScript在检查JSX属性时仅考虑了props,因此您必须使用标记默认的props
?。例:

interface PageProps {
    foo?: string;
    bar: number;
}

export class PageComponent extends React.Component<PageProps, {}> {
    public static defaultProps: Partial<PageProps> = {
        foo: "default"
    };

    public render(): JSX.Element {
        return (
            <span>Hello, world</span>
        );
    }
}

注意:

  • 进行注释是一个好主意defaultPropsPartial<>以便对您的道具进行类型检查,但是您不必为每个必需的属性提供默认值,这是没有意义的,因为必需的属性永远不需要默认值。
  • 使用will strictNullChecks的值时,并需要一个非null的断言(即)或类型保护(即)来移除。这很烦人,因为默认的prop值意味着它实际上永远不会被定义,但是TS不能理解这一流程。这是TS 3.0添加对的显式支持的主要原因之一。this.props.foo``possibly undefined``this.props.foo!``if (this.props.foo) ...``undefined``defaultProps

在TypeScript 2.1之前

这是一样的,但是您没有Partial类型,因此只需忽略Partial<>并为所有必需的prop提供默认值(即使永远不会使用这些默认值),或者完全忽略显式类型注释。

具有[功能组件的](https://facebook.github.io/react/docs/components-and-

props.html#functional-and-class-
components)默认道具

您也可以defaultProps在函数组件上使用,但是必须在FunctionComponentStatelessComponent@types/react版本之前16.7.2)接口中键入函数,以便TypeScript知道defaultProps函数

interface PageProps {
  foo?: string;
  bar: number;
}

const PageComponent: FunctionComponent<PageProps> = (props) => {
  return (
    <span>Hello, {props.foo}, {props.bar}</span>
  );
};

PageComponent.defaultProps = {
  foo: "default"
};

请注意,您不必在Partial<PageProps>任何地方使用,因为FunctionComponent.defaultProps在TS
2.1+中已经将其指定为部分。

另一个不错的替代方法(这是我使用的方法)是对props参数进行解构并直接分配默认值:

const PageComponent: FunctionComponent<PageProps> = ({foo = "default", bar}) => {
  return (
    <span>Hello, {foo}, {bar}</span>
  );
};

然后,您根本不需要defaultProps!请注意,如果您 确实
提供defaultProps了功能组件,它将优先于默认参数值,因为React始终会显式传递defaultProps值(因此,永远不会未定义参数,因此永远不会使用默认参数。)因此,您将使用一个或另一个,而不是两者兼而有之。



 类似资料:
  • 问题与此非常相似,但我的问题集中在默认函数上。(我是前端新手,如果有更正式的名称,请告诉我) 这是代码(我使用的是TypeScript 2.5): 然后,当我尝试渲染这个组件时: 我得到了这个错误; TS2322:类型{}不能赋值给类型Intrinsic属性 类型{}中缺少属性Hello。 我如何解决这个问题?

  • 反应组分 如何在组件中声明输入组件?

  • 我在React函数组件和默认所需道具方面遇到问题。 以下是组件: 我应该能够在不传递道具: 但是,TypeScript引发类型错误属性“message”在类型“{}”中丢失,但在类型“Props”中是必需的: 下面是代码沙盒中的问题:https://codesandbox.io/s/still-microservice-lp7b5?fontsize=14 我不确定我是做错了什么,还是这是打字稿中的

  • 我有一个HOC,它为包装的组件提供一个属性。 我想写的打字稿类型定义,正确地公开由这个HOC创建的组件的道具类型:基本上复制(推断)包装组件的道具类型,并删除我的HOC提供的属性。有可能吗? 在下面的示例中,我有一个HOC,它为任何接受它的包装组件提供了prop。因此,组件应该有props,不包括,这意味着只有。然而TypeScript显然仍然认为组件也应该获得属性。 我使用Typescript

  • 我有一个这样的界面 我想做的是当这个接口所涉及的对象被存储时,将默认为。 我尝试了,但这不起作用。 我确信我在这里做错了什么,并且非常感谢关于我如何实现这一点的一些反馈。

  • 我刚刚用打字稿开始了一个新的反应项目,在功能组件中定义自定义道具时遇到了困难。 我查找了如何定义自定义道具,并找到了一种定义接口的方法,该接口详细描述了我传递给函数的道具类型,但是当我试图在我的主应用程序上运行它时,我得到一个错误消息 类型“{ digit: number; }”不能分配给类型“IntrinsicAttributes”。属性“数字”在类型“内部属性”上不存在。TS2322 我的代码