无法分配给'state',因为它是常量或只读属性

时间:2022-09-11 17:40:08

When I do a search on this issue, I can only find questions that modify this.state directly somewhere in a method body instead of using this.setState(). My problem is that I want to set a starting state in the constructor as follows:

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

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

  public render() {
    ...
  }
}

The app fails to start with the following compile error:

该应用程序无法启动以下编译错误:

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

And this is because in definition of React.Component we have:

这是因为在React.Component的定义中我们有:

readonly state: null | Readonly<S>;

So I'm not sure how to go about this. The official react tutorial in JS directly assigns to this.state and says that it is an acceptable pattern to do so in the constructor, but I can't figure out how to do this with TypeScript.

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

2 个解决方案

#1


30  

This appears to be a recent change in @types/react introduced in commit 542f3c0 which doesn't work very well, considering the fact that Typescript doesn't support assigning parent's readonly fields in derived constructors.

考虑到Typescript不支持在派生构造函数中分配父的只读字段这一事实,这似乎是在commit 542f3c0中引入的@ types / react最近的一个变化,它不能很好地工作。

I suggest rolling back to a previous version of @types/react. Version 16.4.2 appears to be the last one before the unfortunate change has been made.

我建议回滚到以前版本的@ types / react。在不幸的改变之前,版本16.4.2似乎是最后一个版本。

You can pin the version by removing the ^ in your package.json:

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

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

Also check out the discussion about this change on DefinitelyTyped github pull request page

另请参阅DefinitelyTyped github pull请求页面上有关此更改的讨论

#2


21  

Before rolling back (as suggested by @torvin's answer), please read through https://github.com/DefinitelyTyped/DefinitelyTyped/pull/26813#issuecomment-400795486.

在回滚之前(如@ torvin的回答所示),请阅读https://github.com/DefinitelyTyped/DefinitelyTyped/pull/26813#issuecomment-400795486。

This was not meant to be a regression - the solution is to use state as a property. It is better than previous approach (setting state in a constructor) because:

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

  • you don't need constructor at all anymore
  • 你完全不需要构造函数了
  • you can't forget to initialize state (it is now a compile-time error)
  • 你不能忘记初始化状态(现在是编译时错误)

For example:

例如:

type Props {}

type State {
  active: boolean
}

export default class Square extends React.Component<Props, State> {
  public readonly state: State = {
    active: false
  }

  public render() {
    //...
  }
}

Another approach:

另一种方法:

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() {
    //...
  }
}

#1


30  

This appears to be a recent change in @types/react introduced in commit 542f3c0 which doesn't work very well, considering the fact that Typescript doesn't support assigning parent's readonly fields in derived constructors.

考虑到Typescript不支持在派生构造函数中分配父的只读字段这一事实,这似乎是在commit 542f3c0中引入的@ types / react最近的一个变化,它不能很好地工作。

I suggest rolling back to a previous version of @types/react. Version 16.4.2 appears to be the last one before the unfortunate change has been made.

我建议回滚到以前版本的@ types / react。在不幸的改变之前,版本16.4.2似乎是最后一个版本。

You can pin the version by removing the ^ in your package.json:

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

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

Also check out the discussion about this change on DefinitelyTyped github pull request page

另请参阅DefinitelyTyped github pull请求页面上有关此更改的讨论

#2


21  

Before rolling back (as suggested by @torvin's answer), please read through https://github.com/DefinitelyTyped/DefinitelyTyped/pull/26813#issuecomment-400795486.

在回滚之前(如@ torvin的回答所示),请阅读https://github.com/DefinitelyTyped/DefinitelyTyped/pull/26813#issuecomment-400795486。

This was not meant to be a regression - the solution is to use state as a property. It is better than previous approach (setting state in a constructor) because:

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

  • you don't need constructor at all anymore
  • 你完全不需要构造函数了
  • you can't forget to initialize state (it is now a compile-time error)
  • 你不能忘记初始化状态(现在是编译时错误)

For example:

例如:

type Props {}

type State {
  active: boolean
}

export default class Square extends React.Component<Props, State> {
  public readonly state: State = {
    active: false
  }

  public render() {
    //...
  }
}

Another approach:

另一种方法:

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() {
    //...
  }
}