不能分配给"state",因为它是常量或只读属性



当我搜索这个问题时,我只能找到直接在方法体中的某处修改this.state的问题,而不是使用this.setState()。我的问题是我想在构造函数中设置一个起始状态,如下所示:

export default class Square extends React.Component<any, any> {
constructor(props: any) {
super(props);
this.state = {
active: false
};
}
public render() {
...
}
}

应用无法启动,并出现以下编译错误:

Cannot assign to 'state' because it is a constant or a read-only property

这是因为在定义React.Component时,我们有:

readonly state: null | Readonly<S>;

所以我不确定该怎么做。JS中的官方反应教程直接分配给this.state并说在构造函数中这样做是一种可接受的模式,但是我不知道如何使用TypeScript执行此操作。

在回滚之前(按照@torvin的回答的建议(,请通读 https://github.com/DefinitelyTyped/DefinitelyTyped/pull/26813#issuecomment-400795486。

这并不意味着回归 - 解决方案是使用state作为属性。它比以前的方法(在构造函数中设置state(更好,因为:

  • 你根本不需要构造函数
  • 你不能忘记初始化状态(它现在是一个编译时错误(

例如:

type Props {}
type State {
active: boolean
}
export default class Square extends React.Component<Props, State> {
public readonly state: State = {
active: false
}
public render() {
//...
}
}

另一种方法:

type Props {}
const InitialState = {
active: false
}
type State = typeof InitialState
export default class Square extends React.Component<Props, State> {
public readonly state = InitialState
public render() {
//...
}
}

这似乎是提交 542f3c0 中引入的@types/react的最新更改,考虑到 Typescript 不支持在派生构造函数中分配父级的只读字段,它的效果不是很好。

我建议回滚到@types/react的先前版本。版本16.4.2似乎是进行不幸更改之前的最后一个版本。

您可以通过删除package.json中的^来固定版本:

"devDependencies": {
...
"@types/react": "16.4.2",

另请查看 DefinitelyTyped github 拉取请求页面上有关此更改的讨论

由于state是组件的只读属性,因此无法逐字段设置,但您仍然可以执行以下操作:

constructor(props: MyProps) {
super(props);
this.state = {
// include properties here
}
}

最新更新