web-dev-qa-db-ja.com

定数または読み取り専用プロパティであるため、「状態」に割り当てることができません

この問題を検索すると、this.setState()を使用する代わりに、メソッド本体のどこかでthis.stateを直接変更する質問のみを見つけることができます。私の問題は、コンストラクターで次のように開始状態を設定することです。

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でこれを行う方法はわかりません。

36
jeanluc

これは、コミットで導入された@types/reactの最近の変更のように見えます 542f3c TypeScript サポートしない 親の割り当て派生コンストラクターの読み取り専用フィールド。

@types/reactの以前のバージョンにロールバックすることをお勧めします。バージョン16.4.2は、不幸な変更が行われる前の最後のバージョンのようです。

^からpackage.jsonを削除することでバージョンを固定できます:

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

DefinitelyTyped github pull request page でこの変更に関する議論もチェックしてください。

30
torvin

ロールバックする前に(@torvinの答えで示唆されているように)、 https://github.com/DefinitelyTyped/DefinitelyTyped/pull/26813#issuecomment-400795486 を読んでください。

これは回帰を意図したものではありませんでした-解決策はstatepropertyとして使用することです。次の理由により、以前のアプローチ(コンストラクタで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() {
    //...
  }
}
30