webentwicklung-frage-antwort-db.com.de

Wie kann man den Anfangsstatus in React with TypeScript ohne Konstruktor korrekt setzen?

In modernen JS können wir einen Ausgangszustand für eine React-Komponente wie folgt direkt setzen:

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

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

Wenn ich versuche, dies mit TypeScript zu tun, sagt TSLint: "Die Klasseneigenschaft 'state' muss entweder 'private', 'public' oder 'protected' sein. Wenn ich "privat" eingestellt habe, meldet der Linter 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>'. über App. Ich bin mir bewusst, dass ich die Linter-Regeln anpassen kann, um diese Art von Prüfungen zu überspringen, aber die Sichtbarkeit von Klasseneigenschaften im Allgemeinen zu prüfen, ist eine gute Sache, die ich verwenden möchte.

Wenn Sie alle drei Optionen getestet haben, werden TSLint-Fehler nur durch die Auswahl von "public" ausgegeben. Da der Zustand hier jedoch den internen Zustand dieser spezifischen Komponente darstellt, erscheint es ziemlich seltsam, ihn öffentlich zu machen. Mache ich es richtig?

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

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

In allen TS-React-Tutorials, die ich online gefunden habe, wird wie in der alten JS-Syntax ein Konstruktor verwendet.

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

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

Wird das Festlegen der Klasseneigenschaft in Typescript direkt als schlechte Praxis/Stil angesehen?

3
John

Mache ich es richtig?

Ja.

Wird das Festlegen der Klasseneigenschaft in Typescript direkt als schlechter Stil angesehen?

Nein.

Ein etwas besserer Ansatz

Erwägen Sie, den Status als public readonly zu deklarieren und den Modifizierer Readonly zu verwenden.

Dies erfüllt TSLint und bietet gleichzeitig einen gewissen Schutz vor falscher Modifikation (dh, this.setState wird nicht verwendet). Obwohl der Status immer noch von außen ausgesetzt ist, ist dies normalerweise kein Problem.

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>
  }
}

Die TSLint-Regel

Das explizite Deklarieren von Zugriffsmodifizierern ist eine gute Sache, auch wenn dies implizit zu demselben Zugriff führt. Es hilft, Ihren Code klar zu halten, so dass ich diese TSLint-Regel nicht deaktivieren würde.

8
rshepp

Ich würde sagen, die direkte Einstellung der state -Eigenschaft einer React-Komponente ist eine schlechte Übung , es sei denn, Sie geben dem Typ den gleichen Wert wie den State-Parameter für React.Component. Ohne die Annotation bestimmt TypeScript den Typ von this.state vom Initialisierer, überschreibt den Typ aus der Superklasse (die auf dem State-Type-Parameter basiert) und gibt keinen Fehler aus, wenn der Typ des Initialisierers als Untertyp ausgegeben wird des Typparameters. Dies kann später zu Unruhen oder unerwartetem Verhalten führen. Siehe diesen Thread für ein Beispiel.

0
Matt McCutchen