提问者:小点点

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


我不知道如何使用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。我想使用默认值。我还尝试使用了staticdefaultprops=在组件内部,但它没有我所怀疑的效果。

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

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


共3个答案

匿名用户

使用静态默认道具是正确的。对于道具和状态,还应该使用接口,而不是类。

更新2018/12/1:随着时间的推移,TypeScript改进了与defaultProps相关的类型检查。继续阅读最新和最大的用法,直到旧的用法和问题。

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未标记为可选(即foo?:string),即使它不是JSX属性所必需的。标记为可选意味着它可以是未定义的,但实际上它永远不会是未定义的,因为defaultProps提供了一个默认值。想象一下类似于如何将函数参数标记为可选,或使用默认值,但不是两者都有,但这两者都意味着调用不需要指定值。TypeScript 3.0以类似的方式处理defaultProps,这对React用户来说非常酷

在TypeScript 3.0实现编译器对defaultProps的支持之前,您仍然可以使用它,并且它在运行时100%适用于React,但是由于TypeScript在检查JSX属性时只考虑道具,因此您必须将具有默认值的道具标记为可选的<代码>?.示例:

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>
        );
    }
}

请注意:

  • 这是一个好主意注释defaultProps部分

这是一样的,但是您没有Partial类型,所以只需省略Partial即可

您也可以在函数组件上使用defaultProps,但是您必须将您的函数键入到FunctionComponentStatelessComponent16.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

另一个不错的选择(这就是我使用的)是分解props参数并直接指定默认值:

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

那么你根本不需要defaultProps!请注意,如果在函数组件上提供了defaultProps,它将优先于默认参数值,因为React将始终显式传递defaultProps值(因此参数永远不会未定义,因此永远不会使用默认参数)所以你会用其中一个,而不是两个。

匿名用户

对于Typescript 2.1,使用部分

export interface Props {
    obj: Model,
    a: boolean
    b: boolean
}

public static defaultProps: Partial<Props> = {
    a: true
};

匿名用户

有了TypeScript 3.0,这个问题有了一个新的解决方案:

export interface Props {
    name: string;
}

export class Greet extends React.Component<Props> {
    render() {
        const { name } = this.props;
        return <div>Hello ${name.toUpperCase()}!</div>;
    }
    static defaultProps = { name: "world"};
}

// Type-checks! No type assertions needed!
let el = <Greet />

请注意,要使其正常工作,您需要比16.4更新版本的@types/react。6。它适用于16.4。11