TypeScript + React:正确定义 defaultProps
Posted
技术标签:
【中文标题】TypeScript + React:正确定义 defaultProps【英文标题】:TypeScript + React: defining defaultProps correctly 【发布时间】:2017-02-19 00:09:08 【问题描述】:假设你这样定义你的组件:
interface IProps
req: string;
defaulted: string;
class Comp extends React.Component<IProps, void>
static defaultProps =
defaulted: 'test',
;
render()
const defaulted = this.props;
return (
<span>defaulted.toUpperCase()</span>
);
当你想使用它时,TypeScript 需要你提供 defaulted
属性,即使它是在 defaultProps
中定义的:
<Comp req="something" /> // ERROR: TypeScript: prop 'defaulted' is required
但是,如果你像这样定义 props 接口:
interface IProps
req: string;
defaulted?: string; // note the ? here
那么你不能使用它:
render()
const defaulted = this.props; // ERROR: prop 'defaulted' possibly undefined
return (
<span>defaulted.toUpperCase()</span>
);
如何正确定义 IProps、defaultProps 和组件以使类型有意义?
编辑:
我正在使用strictNullChecks
标志。
【问题讨论】:
“我把它们默认了” ...你呢? 我很确定我做到了:static defaultProps: IDefaultProps = validate: () => null, defaultValue: '', ;
好吧,让我换个说法:它们似乎没有在您在问题中显示的代码中被默认。给minimal reproducible example。
如果添加 ? (就像您使用索引一样)它们将是可选的,并且您不会收到有关可能未定义的错误。然后,在你使用它们的地方默认它们的值。
@Stuart 但是我不能在组件中使用它 - TypeScript 抱怨它们可能是未定义的
【参考方案1】:
我有一个包含以下代码的示例(ComponentBase 只是我对 React.Component 的包装)。
编辑:更新代码以使用“strictNullChecks”设置
interface IExampleProps
name: string;
otherPerson?: string;
/**
* Class with props with default values
*
* @class Example
* @extends ComponentBase<IComponentBaseSubProps, >
*/
export class Example extends ComponentBase<IExampleProps, >
public static defaultProps: IExampleProps =
otherPerson: "Simon",
name: "Johnny"
;
constructor(props: IExampleProps)
super(props);
public render(): JSX.Element
const person: string = this.props.otherPerson === undefined ? "" : this.props.otherPerson;
return(
<div>
<h1><small>Message by ComponentBaseSub: Hello this.props.name and person </small></h1>
</div>
);
我在使用 Visual Studio Code、TypeScript 2.0.3、TSLint 0.5.39 时没有任何问题。
【讨论】:
可能是因为this.props.otherPerson
可以成为undefined
。尝试添加一个变量,比如const person: string = this.props.otherPerson;
,看看它是否抱怨
@Idefixx 将该变量准确添加到“渲染”方法的主体中仍然不会导致您报告的问题。
你可以在github.com/boxstart/react-typescript-samples 上查看我的反应样本叉。示例 02 包含我上面示例中的可选属性和 defaultProps。如果您在使用此项目时仍然收到警告/错误,那么您可能需要在您的环境中查找设置。
啊啊啊,我正在使用strictNullChecks
标志。试试看
试过了,确实我也收到了消息。这并不是真正意外的行为,因为在对您的组件(jsx / tsx)的引用中,可以将属性设置为未定义,因此在您的渲染方法中,属性值仍然是“未定义”,尽管默认值在组件中。【参考方案2】:
更简单的是
<span>(defaulted as string).toUpperCase()</span>
属性的工作方式相同。如果Foo
需要barProp
属性而Parent
不需要并且通过defaultProps
得到它,Parent
的渲染方法可以做到
<Foo barProp=this.props.barProp as string />
【讨论】:
谢谢!使用 defaultProps 进行空检查会破坏使用 defaultProps 的好处【参考方案3】:如果你确定 prop 会有一个默认值,你可以使用 null 断言类型操作符,像这样:
render()
const defaulted = this.props;
return (
<span>defaulted!.toUpperCase()</span>
);
【讨论】:
以上是关于TypeScript + React:正确定义 defaultProps的主要内容,如果未能解决你的问题,请参考以下文章
如何正确定义样式组件的引用(React.RefObject<StyledComponentClass>)(对于 TypeScript)?
调度自定义事件并测试它是不是被正确触发(React TypeScript,Jest)
如何在 React 上正确使用带有样式组件画布的 TypeScript 类型
对 React 中如何使用接口(TypeScript)感到困惑