reactjs – 为什么null React组件状态初始化得到`never`类型?
在组件的构造函数外部将组件的状态初始化为null时,状态在render函数中的类型永远不会.
但是,在构造函数中初始化状态时,状态具有正确的类型. 根据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
它们在TypeScript中是不同的,因为在类体(而不是在构造函数中)中分配状态会在PersonSelector中声明状态,从而覆盖基类React.Component中的声明.在TypeScript中,允许覆盖声明具有不同的,更严格的类型,与基类中相同属性的类型单向兼容. 初始化时没有类型注释,此类型由值的类型确定: class PersonSelector extends React.Component<Props,State> { // DOES NOT WORK: state = { selected: null }; 您可以按预期看到状态的类型为{selected:null}.它永远不会在这个代码中 const { selected } = this.state; let selectedLabel = <div>None selected</div>; if (selected) { 因为在if语句内部,所选的类型变窄,使用选中的信息为true. Null永远不会是真的,因此类型变为 正如在其他答案中建议的那样,您可以在类主体中初始化时明确注释State class PersonSelector extends React.Component<Props,State> { state: State = { selected: null }; 更新以阐明类主体中的初始化与构造函数中的赋值不同 在构造函数中设置状态时 constructor(props: Props) { super(props); this.state = { selected: null }; } 您正在将值分配给已在基类中声明的状态属性.基类是React.Component< Props,State>和 分配不会更改属性的类型 – 无论分配的值如何,它都将保持为State. 当你在类体中设置状态时,它不仅仅是赋值 – 它是类属性的声明,并且每个声明都为声明的实体提供一种类型 – 显式地通过类型注释,或隐式地从初始值推断出来.即使属性已存在于基类中,也会发生此类型的输入.我在文档中找不到任何确认这一点的内容,但是github issue确实描述了这种行为,并确认有时它违背了开发人员的意图(到目前为止还没有用该语言实现的解决方案). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |