- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我不知道如何使用 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 组件都依赖于它们,不使用它们不是一个选择。
最佳答案
使用 static defaultProps
是正确的。您还应该为 Prop 和状态使用接口(interface),而不是类。
更新 2018/12/1:TypeScript 改进了与 defaultProps
相关的类型检查随着时间的推移。继续阅读以了解最新和最重要的用法,直至旧用法和问题。
特别是 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 3.0 实现对 defaultProps
的编译器支持之前你仍然可以使用它,它在运行时 100% 与 React 一起工作,但由于 TypeScript 在检查 JSX 属性时只考虑 Prop ,你必须使用 ?
将具有默认值的 Prop 标记为可选。 .示例:
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
并需要一个非空断言(即 this.props.foo!
)或类型保护(即 if (this.props.foo) ...
)来删除 undefined
.这很烦人,因为默认的 prop 值意味着它实际上永远不会未定义,但 TS 不理解这个流程。这是 TS 3.0 添加对 defaultProps
明确支持的主要原因之一。 .这同样有效,但你没有 Partial
类型,所以省略 Partial<>
并为所有必需的 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
值(所以参数永远不会未定义,因此永远不会使用默认参数。)所以你会使用一个或另一个,而不是两个。
关于reactjs - 使用 TypeScript 的 React 组件中的默认属性值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37282159/
我收到此错误消息: .rvm/gems/ruby-2.5.1/bin/ruby_executable_hooks:24:in `' 我重新安装了 Ruby rvm reinstall ruby-2.5
我开始从事 WPF Ribbon 开发,非常好! 我的问题是找到(免费)基本图标(如文件保存/打开/等,剪切/粘贴/等)。 你有什么建议吗? 最佳答案 你看过Visual Studio Icon Li
我只找到经典的声音ID,但我需要Chord(默认)日历警报。如何播放声音? ks #define systemSoundID 1315 AudioServicesPlaySystemSound (s
在 Magento 中创建货件时,有一个复选框可让您“通过电子邮件发送货件副本”。 默认情况下未选中。有谁知道我需要编辑哪个文件才能默认设置为“选中”? 最佳答案 这是一个app/design/adm
我有一个简单的 IValueConverter,它只使用 TypeConverter 进行转换。但是,在某些情况下,提供的 TypeConverter 会失败。 如果转换器未提供 Binding,我想
我正在阅读教程,默认 Activity 是一个扩展另一个类的类,它所拥有的只是一个覆盖方法。应用程序如何工作,因为它不做任何其他事情?我很困惑! 最佳答案 父类 Activity 为您处理一切。 关于
我刚刚开始研究游戏框架。我正在尝试构建 rest api,并将 postgresql 用于我的数据库连接。这是我第一次同时使用 play 和 postgre。我在 build.sbt 中建立了一个数据
是否可以创建具有以下属性的 python 对象: class Foo: def __default_method__(x): return x f = Foo() f(10) > 10
我是 jQuery 的新手,遇到了一个烦人的问题。我有一些登录字段,当该字段为空时会填充默认文本,然后在单击时删除。 我的问题是,当用户保存了他们的用户名/密码(使用浏览器)时,如果他们返回页面,登录
考虑这个代码片段: void Foo(std::string str1, std::string str2) {} template void Bar() { Foo(Types{}...);
我正在编写一个简单的 C 程序,我应该用缓冲区溢出来攻击它。所以,我不想在编译时使用任何标志。如何消除使用的默认标志? # readelf -p .GCC.command.line stack Str
考虑这个代码片段: void Foo(std::string str1, std::string str2) {} template void Bar() { Foo(Types{}...);
我有以下代码[这是一道面试题]: #include #include using namespace std; class A{ public: A(){ cout co
我想在 Autofac 中为每个匹配的生命周期范围注册创建一个实例,但偶尔需要从全局容器(没有匹配的生命周期范围)请求一个实例。在不存在匹配生命周期范围的情况下,我想给出一个顶级实例而不是抛出异常。
我正在做一个收集单词共现的修改版本,所以我编写了自己的 javascript,我正在跟踪三个对象中的出现。但是,一旦对象变大(约 800 万、300 万和 172000),每 100000 个句子需要
我正在使用 pykalman 模块中的 KalmanFilter,我想知道它如何处理缺失的观察结果。根据文档: In real world systems, it is common to have
我有一个应用了 RenderTransform 的 Canvas ,如下所示: 谁能告诉我这些值是什么意思?我似乎无法找到用于解析这些值的转换器。 最佳答案 如 RenderTransform是 T
我是 Linux 的新手,现在使用 CentOS 6。我在这里使用 MySQL 工作台,每当我尝试添加新连接时,它都会询问我默认的 key 环密码。我真的不知道,这个密码是从哪里设置的,我之前没有设置
我在 Ubuntu 18.04 上工作。我没有定义 GL_GLEXT_PROTOTYPES .我使用 glXGetProcAddress 加载“核心”OpenGL 函数.我的申请链接到 /usr/li
我按照文档中的示例添加了对使用 asio 加载 HTTPS 站点的支持,这意味着我调用 ctx.set_default_verify_paths();使用系统默认路径来查找证书。 然而,我得到:una
我是一名优秀的程序员,十分优秀!