带有类组件的默认道具
使用static defaultProps
是正确的。您还应该为道具和状态使用接口,而不是类。
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
没有标记为可选(即),即使它不是 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 属性时只考虑道具,你必须将具有默认值的道具标记为可选?
。例子:
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<>
以便它对你的 props 进行类型检查,但你不必为每个必需的属性提供默认值,这是没有意义的,因为必需的属性永远不需要默认值。
- 当使用
strictNullChecks
的值时,this.props.foo
将possibly undefined
需要一个非空断言(即this.props.foo!
)或类型保护(即if (this.props.foo) ...
)来删除undefined
。这很烦人,因为默认的 prop 值意味着它实际上永远不会未定义,但 TS 不理解这个流程。这是 TS 3.0 明确支持defaultProps
.
在 TypeScript 2.1 之前
这同样适用,但您没有Partial
类型,因此只需省略Partial<>
并为所有必需的道具提供默认值(即使永远不会使用这些默认值)或完全省略显式类型注释。
您也可以defaultProps
在函数组件上使用,但您必须将函数键入FunctionComponent
(StatelessComponent
在@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
值(因此参数永远不会未定义,因此永远不会使用默认参数。)所以你会使用一个或另一个,而不是两者。