javascript - Vanilla JS React-komponenter i TypeScript-filer (ts, tsx)


Jag undrade bara om det på något sätt är möjligt att implementera React-klasskomponenter på samma sätt som de implementeras i Vanilla JS men i en TypeScript-applikation i .tsx-filer?

TypeScript-kompilatorn varnar mig att det misslyckades att kompilera, men hur är det, att även om TypeScript praktiskt taget är JavaScript och kan kompilera vanliga JavaScript-funktioner och många fler saker från JS, kunde den inte kompilera vanliga JavaScript-komponenter eftersom den begär att man implementerar komponenters egenskaper och tillståndsgränssnitt för att skicka dem till komponenten?

Följande kod jag tillhandahåller resulterar i kompileringsfel i en TypeScript-applikation men inte i vanlig JS:

export class Toggle extends React.Component {
  constructor(props: any) {
    super(props);
    this.state = { isToggleOn: true };

    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(prevState => ({
      isToggleOn: !prevState.isToggleOn
    }));
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? "ON" : "OFF"}
      </button>
    );
  }
}

Felmeddelandet ser ut så här med understruken .isToggleOn i koden:

TypeScript error in C:/.../Toggle.tsx(51,30)
Property 'isToggleOn' does not exist on type 'Readonly<{}>'.  TS2339

Observera att när jag ändrar den första raden till: export class Toggle extends React.Component<{}, ToggleState> och deklarerar ToggleState-gränssnittet, löses problemet.

Svar #1

Enkel JavaScript bryr sig inte om argumenten till Props och State.
I TypeScript kommer kompilatorn inte att tycka om det, så det är där felet kommer ifrån.
Utan att ha en ToggleState uttryckligen angiven skulle jag föreslå att man anger en typ för tillståndet i komponentens argument.
detta är min lösning:

export class Toggle extends React.Component<{}, { isToggleOn: boolean }> {
  constructor(props: any) {
    super(props);
    this.state = { isToggleOn: true };

    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(prevState => ({
      isToggleOn: !prevState.isToggleOn
    }));
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? "ON" : "OFF"}
      </button>
    );
  }
}

Den bästa metoden för kanske ett större projekt är att separera de två, för att ha en mer läsbar kod.