- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
当在组件的构造函数之外将组件的状态初始化为 null
时,状态在渲染函数中的类型为 never
。
但是,当在构造函数中初始化状态时,状态具有正确的类型。
根据 StackOverflow 上关于这两种初始化状态(在 babeled JS 中)的大多数问题,这两种方法应该是等价的。但是,在 Typescript 中,它们不是。这是错误还是预期的行为?
import * as React from "react";
import * as ReactDOM from "react-dom";
interface Person {
name: string;
address: string;
}
interface Props {
items: Person[];
}
interface State {
selected: Person | null;
}
class PersonSelector extends React.Component<Props, State> {
// DOES NOT WORK:
state = {
selected: null
};
constructor(props: Props) {
super(props);
// WORKS:
// this.state = {
// selected: null
// };
}
handleClick = (item: Person) => {
this.setState({
selected: item
});
};
render() {
const { selected } = this.state;
let selectedLabel = <div>None selected</div>;
if (selected) {
selectedLabel = <div>You selected {selected.name}</div>;
}
return (
<div>
{selectedLabel}
<hr />
{this.props.items.map(item => (
<div onClick={() => this.handleClick(item)}>{item.name}</div>
))}
</div>
);
}
}
const people: Person[] = [
{ name: "asdf", address: "asdf asdf" },
{ name: "asdf2", address: "asdf asdf2" }
];
document.write('<div id="root"></div>');
ReactDOM.render(
<PersonSelector items={people} />,
document.getElementById("root")
);
这是 CodeSandbox 上的示例代码:https://codesandbox.io/s/10l73o4o9q
最佳答案
According to most questions on StackOverflow about the two ways to initialize state (in babeled JS), these two methods should be equivalent. However, in Typescript, they are not.
它们在 TypeScript 中是不同的,因为分配 state
在类主体中(不在构造函数中)声明 state
在 PersonSelector
, 覆盖基类中的声明 React.Component
.在 TypeScript 中,重写声明允许具有不同的、更严格的类型,与基类中相同属性的类型单向兼容。
在没有类型注释的情况下初始化时,此类型由值的类型确定:
class PersonSelector extends React.Component<Props, State> {
// DOES NOT WORK:
state = {
selected: null
};
您可以看到 state
的类型是{selected: null}
, 正如预期的那样。变成never
在这段代码中
const { selected } = this.state;
let selectedLabel = <div>None selected</div>;
if (selected) {
因为里面if
语句,selected
的类型缩小范围,使用 selected
的信息是true
. Null 永远不可能为真,因此类型变为 never
.
按照其他答案中的建议,您可以注释 State
在类主体中初始化时显式
class PersonSelector extends React.Component<Props, State> {
state: State = {
selected: null
};
更新以阐明类体中的初始化与构造函数中的赋值有何不同
当您设置 state
时在构造函数中
constructor(props: Props) {
super(props);
this.state = {
selected: null
};
}
您正在将值分配给 state
在基类中声明时已经存在的属性。基类是React.Component<Props, State>
, 和 state
声明那里的属性(property)有State
类型,取自 <Props, State>
中的第二个通用参数.
赋值不会改变属性的类型 - 它仍然是 State
,无论分配的值如何。
当您设置 state
时在类主体中,它不仅仅是赋值——它是类属性的声明,每个声明都为声明的实体提供一个类型——通过类型注释显式地或隐式地从初始值推断。即使该属性已经存在于基类中,也会发生这种键入。我在文档中找不到任何可以证实这一点的内容,但是有 github issue准确描述了这种行为,并确认有时它违背了开发人员的意图(目前还没有用该语言实现的解决方案)。
关于reactjs - 为什么 null React 组件状态初始化得到的是 `never` 类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51201315/
我是 Spring 新手,这就是我想要做的事情: 我正在使用一个基于 Maven 的库,它有自己的 Spring 上下文和 Autowiring 字段。 它的bean配置文件是src/test/res
我在我的测试脚本中有以下列表初始化: newSequenceCore=["ls", "ns", "*", "cm", "*", "ov", "ov", "ov", "ov", "kd"] (代表要在控
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: Class construction with initial values 当我查看 http://en.
我得到了成员变量“objectCount”的限定错误。编译器还返回“ISO C++ 禁止非常量静态成员的类内初始化”。这是主类: #include #include "Tree.h" using n
我有如下所示的a.h class A { public: void doSomething()=0; }; 然后我有如下所示的b.h #include "a.h" class b: publi
我需要解析 Firebase DataSnapshot (一个 JSON 对象)转换成一个数据类,其属性包括 enum 和 list。所以我更喜欢通过传递 DataSnapshot 来手动解析它进入二
我使用 JQuery 一段时间了,我总是使用以下代码来初始化我的 javascript: $(document).ready( function() { // Initalisation logic
这里是 Objective-C 菜鸟。 为什么会这样: NSString *myString = [NSString alloc]; [myString initWithFormat:@"%f", s
我无法让核心数据支持的 NSArrayController 在我的代码中正常工作。下面是我的代码: pageArrayController = [[NSArrayController alloc] i
我对这一切都很陌生,并且无法将其安装到我的后端代码中。它去哪里?在我的页脚下面有我所有的 JS? 比如,这是什么意思: Popup initialization code should be exec
这可能是一个简单的问题,但是嘿,我是初学者。 所以我创建了一个程序来计算一些东西,它目前正在控制台中运行。我决定向其中添加一个用户界面,因此我使用 NetBeans IDE 中的内置功能创建了一个 J
我有 2 个 Controller ,TEST1Controller 和 TEST2Controller 在TEST2Controller中,我有一个initialize()函数设置属性值。 如果我尝
据我所知, dependentObservable 在声明时会进行计算。但如果某些值尚不存在怎么办? 例如: var viewModel ={}; var dependentObservable1 =
我正在阅读 POODR 这本书,它使用旧语法进行默认值初始化。我想用新语法实现相同的功能。 class Gear attr_reader :chainring, :cog, :wheel de
我按照 polymer 教程的说明进行操作: https://www.polymer-project.org/3.0/start/install-3-0 (我跳过了可选部分) 但是,在我执行命令“po
很抱歉问到一个非常新手的Kotlin问题,但是我正在努力理解与构造函数和初始化有关的一些东西。 我有这个类和构造函数: class TestCaseBuilder constructor(
假设我们有一个包含 30 列和 30 行的网格。 生命游戏规则简而言之: 一个小区有八个相邻小区 当一个细胞拥有三个存活的相邻细胞时,该细胞就会存活 如果一个细胞恰好有两个或三个活的相邻细胞,那么它就
我是 MQTT 和 Android 开放附件“AOA” 的新手。在阅读教程时,我意识到,在尝试写入 ByteArrayOutputStream 类型的变量之前,应该写入 0 或 0x00首先到该变量。
我有 2 个 Controller ,TEST1Controller 和 TEST2Controller 在TEST2Controller中,我有一个initialize()函数设置属性值。 如果我尝
我有一个inotify /内核问题。我正在使用“inotify” Python项目进行观察,但是,我的问题仍然是固有的关于inotify内核实现的核心。 Python inotify项目处理递归ino
我是一名优秀的程序员,十分优秀!