使用类组件的默认属性
使用static defaultProps
是正确的。您还应该使用接口而不是类来定义props和state。
更新于2018/12/1: TypeScript随着时间的推移已经改进了与defaultProps
相关的类型检查。请继续阅读以获取最新和最好的用法,包括旧用法和问题。
对于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
没有被标记为可选的(即foo?: string
),即使它作为JSX属性不是必需的。将其标记为可选意味着它可以是undefined
,但实际上它永远不会是undefined
,因为defaultProps
提供了默认值。可以将其类比于您可以将函数参数标记为可选或具有默认值,但不能同时具有这两种特性,但两者都意味着调用不需要指定值。 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 完全兼容,但由于 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>
);
}
}
请注意:
- 使用
Partial<>
对
defaultProps
进行注释是个好主意,这样它就可以针对您的props进行类型检查,但您不必为每个必需属性提供默认值,因为需要默认值的必需属性没有任何意义。
- 当使用
strictNullChecks
时,
this.props.foo
的值将为
possibly undefined
,需要使用非空断言(即
this.props.foo!
)或类型保护(即
if (this.props.foo) ...
)来消除
undefined
。这很让人恼火,因为默认prop值意味着它实际上永远不会是undefined,但TS并没有理解这个流程。这是TS 3.0明确支持
defaultProps
的主要原因之一。
在TypeScript 2.1之前:
- 这个工作方式相同,但您没有
Partial
类型,因此只需省略
Partial<>
并为所有必需的props提供默认值(即使永远不会使用那些默认值),或者完全省略显式类型注释。
你也可以在函数组件中使用defaultProps
,但是你需要将函数类型定义为FunctionComponent
(在@types/react
版本16.7.2
之前为StatelessComponent
),这样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>
,因为在TS 2.1+中,
FunctionComponent.defaultProps
已经被指定为部分。
另一个不错的选择(这是我使用的)是解构您的
props
参数并直接分配默认值:
const PageComponent: FunctionComponent<PageProps> = ({foo = "default", bar}) => {
return (
<span>Hello, {foo}, {bar}</span>
);
};
那么您根本不需要defaultProps
!请注意,如果您在函数组件上提供了defaultProps
,它将优先于默认参数值,因为React始终会明确传递defaultProps
值(因此参数永远不会是未定义的,因此不会使用默认参数)。所以您只需要使用其中一个,而不是两个。
static defaultProps
是正确的。你能发布那段代码吗? - Aaron Beall