Die Eigenschaft 'value' ist für den Typ 'Readonly <{}>' nicht vorhanden.

154

Ich muss ein Formular erstellen, das etwas basierend auf dem Rückgabewert einer API anzeigt. Ich arbeite mit folgendem Code:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    alert('A name was submitted: ' + this.state.value); //error here
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" value={this.state.value} onChange={this.handleChange} /> // error here
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

Ich erhalte die folgende Fehlermeldung:

error TS2339: Property 'value' does not exist on type 'Readonly<{}>'.

Ich habe diesen Fehler in den beiden Zeilen erhalten, in denen ich den Code kommentiert habe. Dieser Code gehört nicht einmal mir, ich habe ihn von der offiziellen Reaktionsseite ( https://reactjs.org/docs/forms.html ) erhalten, aber er funktioniert hier nicht.

Ich benutze das Create-React-App-Tool.

Luis Henrique Zimmermann
quelle
Ihr Problem liegt woanders - siehe Diese Demo
Ted
Ich weiß, es funktioniert auf all diesen "Compiler" -Websites, aber sie haben mir geraten, dies für das Projekt github.com/Microsoft/TypeScript-React-Starter zu verwenden , und über den TypeScript-Compliter funktioniert es nicht
Luis Henrique Zimmermann

Antworten:

262

Das Component ist wie folgt definiert :

interface Component<P = {}, S = {}> extends ComponentLifecycle<P, S> { }

Dies bedeutet, dass der Standardtyp für den Status (und die Requisiten) lautet : {}.
Wenn Ihre Komponente valueden Status haben soll, müssen Sie sie folgendermaßen definieren:

class App extends React.Component<{}, { value: string }> {
    ...
}

Oder:

type MyProps = { ... };
type MyState = { value: string };
class App extends React.Component<MyProps, MyState> {
    ...
}
Nitzan Tomer
quelle
3
omg, ty dude, es hat jetzt funktioniert, antworte mir noch eine Sache, diese Syntax hängt mit TypeScript zusammen, oder? weil in reagieren offizielle Seite hat es nichts ähnliches
Luis Henrique Zimmermann
3
Ja, dies ist streng typoskriptbezogen.
Nitzan Tomer
1
Die richtige Definition lautet: class Square erweitert React.Component <{value: string}, {}> {...}
Rodrigo Perez Burgues
57

Zusätzlich zur Antwort von @ nitzan-tomer haben Sie auch die Möglichkeit, Inferfaces zu verwenden :

interface MyProps {
  ...
}

interface MyState {
  value: string
}

class App extends React.Component<MyProps, MyState> {
  ...
}

// Or with hooks, something like

const App = ({}: MyProps) => {
  const [value, setValue] = useState<string>(null);
  ...
};

Beides ist in Ordnung, solange Sie konsequent sind.

Löwe
quelle
1
Bitte fassen Sie zusammen, was konsistent im Kontext Ihres Beitrags bedeutet, damit es möglich ist, seinen vollen Wert zu erhalten, ohne den mittleren Artikel lesen zu müssen (was ein großartiger nützlicher Link ist, danke).
Karl Richter
8

Das Problem ist, dass Sie nicht angegeben haben, dass Ihr Schnittstellenstatus einen durch Ihren geeigneten Variablentyp des 'Werts' ersetzen soll.

Hier ist eine gute Referenz

interface AppProps {
   //code related to your props goes here
}

interface AppState {
   value: any
}

class App extends React.Component<AppProps, AppState> {
  // ...
}
Minuka ArTy Weerathunga
quelle
0

event.targetist vom Typ, EventTargetder nicht immer einen Wert hat. Wenn es sich um ein DOM-Element handelt, müssen Sie es in den richtigen Typ umwandeln:

handleChange(event) {
    this.setState({value: (event.target as HTMLInputElement).value});
}

Dies wird auch auf den "richtigen" Typ für die Zustandsvariable schließen, obwohl es wahrscheinlich besser ist, explizit zu sein

Apokryfos
quelle
Ich denke, er bekommt den Fehler, wenn er versucht, die Zeichenfolge im Konstruktor zu initialisieren, nicht im Ereignishandler
Ray_Poly