web-dev-qa-db-ja.com

ReactコンストラクターなしのTypeScriptで初期状態を正しく設定する方法は?

現代のJSでは、次のようにReactコンポーネントの初期状態を直接設定できます。

class App extends React.Component {
  state = {value: 10}

  render() {
    return <div>{this.state.value}</div>
  }
}

TypeScriptでこれを行おうとすると、TSLintは「クラスプロパティ 'state'を 'private'、 'public'、または 'protected'にマークする必要があります」と言います。 「プライベート」に設定すると、リンターはClass 'App' incorrectly extends base class 'Component<{}, { value: number; }, any>'. Property 'state' is private in type 'App' but not in type 'Component<{}, { value: number; }, any>'. on App。私はリンタールールを微調整してこの種のチェックをスキップできることを知っていますが、クラスプロパティの可視性をチェックすることは私が利用したい良いことです。

3つのオプションすべてをテストした後、「パブリック」を選択しただけでは、TSLintはエラーをスローしません。ただし、ここでの状態はこの特定のコンポーネントの内部状態を表しているため、パブリックに設定するのはかなり奇妙に思えます。私はそれを正しい方法でやっていますか?

class App extends React.Component<{}, { value: number }> {
  public state = { value: 10 };

  public render() {
    return <div>{this.state.value}</div>;
  }
}

オンラインで見つけたすべてのTS-Reactチュートリアルでは、古いJS構文のようにコンストラクターが使用されます。

class App extends React.Component<{}, { value: number }> {
  constructor(props: any) {
    super(props);
    this.state = { value: 10 };
  }

  public render() {
    return <div>{this.state.value}</div>;
  }
}

クラスプロパティの設定は、Typescriptの悪い習慣/スタイルと直接考えられていますか?

8
John

私はそれを正しい方法でやっていますか?

はい。

クラスプロパティの設定は、Typescriptで直接悪いスタイルと見なされますか?

いや.

少し良いアプローチ

状態をpublic readonlyとして宣言し、 Readonly modifier を使用することを検討してください。

これはTSLintを満たすと同時に、誤って変更されないように保護します(つまり、this.setStateを使用しない)。状態はまだ外部に公開されていますが、これは通常問題にはなりません。

interface IState {
  value: number;
}

class App extends React.Component<{}, IState> {
  public readonly state: Readonly<IState> = {
    value: 10
  }

  public render() {
    return <div>{this.state.value}</div>
  }
}

TSLintルール

暗黙的に同じアクセスが発生する場合でも、アクセス修飾子を明示的に宣言することは良いことです。コードを明確に保つのに役立つので、このTSLintルールを無効にしません。

14
rshepp

Reactコンポーネントのstateプロパティを直接設定するのは悪い練習ですunlessReact.Componentの状態型パラメーターと同じになるように型に注釈を付けます。注釈がない場合、TypeScriptは初期化子からthis.stateの型を決定し、スーパークラス(型に基づいて初期化子からの型が型パラメーターのサブタイプである場合、エラーは発生しません。これにより、後で不健全または予期しない動作が発生する可能性があります。 this thread を参照してください例。

0
Matt McCutchen