我不知道如何使用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组件都依赖于它们,不使用它们不是一种选择。
最佳答案
带有类组件的默认 Prop
使用static defaultProps
是正确的。您还应该使用接口(interface)(而不是类)作为 Prop 和状态。
更新2018/12/1 :随着时间的推移,TypeScript改进了与defaultProps
相关的类型检查。继续阅读以获取最新和最佳用法,直至较老的用法和问题。
对于TypeScript 3.0及更高版本
TypeScript专门使用added support for 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属性所必需的。标记为可选将意味着它可以是undefined
,但是实际上它永远不会是undefined
,因为defaultProps
提供了默认值。认为它类似于you can mark a function parameter optional, or with a default value, but not both, yet both mean the call doesn't need to specify a value。 TypeScript 3.0+以类似的方式对待defaultProps
,这对于React用户真的很酷! defaultProps
没有显式类型注释。推断出它的类型,并由编译器用来确定所需的JSX属性。您可以使用defaultProps: Pick<PageProps, "foo">
来确保defaultProps
与PageProps
的子集匹配。关于此警告的更多信息是explained here。 @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>
);
}
}
注意:
defaultProps
注释Partial<>
是个好主意,这样它就可以对您的 Prop 进行类型检查,但是您不必为每个必需的属性提供默认值,这是没有意义的,因为必需的属性永远不需要默认值。 strictNullChecks
时,this.props.foo
的值将为possibly undefined
,并且需要非null断言(即this.props.foo!
)或类型保护(即if (this.props.foo) ...
)才能删除undefined
。这很烦人,因为默认的prop值意味着它实际上永远不会被定义,但是TS不能理解这一流程。这是TS 3.0添加了对defaultProps
的显式支持的主要原因之一。 在TypeScript 2.1之前
效果相同,但是您没有
Partial
类型,因此只需省略Partial<>
并为所有必需 Prop 提供默认值(即使永远不会使用这些默认值)或完全省略显式类型注释。带Functional Components的默认 Prop
您也可以在函数组件上使用
defaultProps
,但是必须在FunctionComponent
(版本StatelessComponent
之前的@types/react
中为16.7.2
)接口(interface)中键入函数,以便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
值(因此,永远不会定义参数,因此永远不会使用默认参数。) d使用一个或另一个,而不是两者都使用。关于reactjs - 使用TypeScript在React组件中的默认属性值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37282159/