Typoskript: Reagiert auf Ereignistypen


129

Was ist der richtige Typ für React-Ereignisse? Anfangs habe ich nur anyder Einfachheit halber verwendet. Jetzt versuche ich, Dinge aufzuräumen und die Verwendung anyvollständig zu vermeiden .

Also in einer einfachen Form wie dieser:

export interface LoginProps {
  login: {
    [k: string]: string | Function
    uname: string
    passw: string
    logIn: Function
  }
}
@inject('login') @observer
export class Login extends Component<LoginProps, {}> {
  update = (e: React.SyntheticEvent<EventTarget>): void => {
    this.props.login[e.target.name] = e.target.value
  }
  submit = (e: any): void => {
    this.props.login.logIn()
    e.preventDefault()
  }
  render() {
    const { uname, passw } = this.props.login
    return (
      <div id='login' >
        <form>
          <input
            placeholder='Username'
            type="text"
            name='uname'
            value={uname}
            onChange={this.update}
          />
          <input
            placeholder='Password'
            type="password"
            name='passw'
            value={passw}
            onChange={this.update}
          />
          <button type="submit" onClick={this.submit} >
            Submit
          </button>
        </form>
      </div>
    )
  }
}

Welchen Typ verwende ich hier als Ereignistyp?

React.SyntheticEvent<EventTarget>scheint nicht zu funktionieren , wie ich einen Fehler , dass nameund valuenicht existieren auf target.

Eine allgemeinere Antwort für alle Veranstaltungen wäre sehr dankbar.

Vielen Dank

Antworten:


144

Die SyntheticEvent- Schnittstelle ist generisch:

interface SyntheticEvent<T> {
    ...
    currentTarget: EventTarget & T;
    ...
}

Und das currentTargetist ein Schnittpunkt der generischen Einschränkung und EventTarget.
Da auch Ihre Veranstaltungen durch ein Eingangselement verursacht werden , sollten Sie die Verwendung FormEvent( in Definitionsdatei , die reagiert docs ).

Sollte sein:

update = (e: React.FormEvent<HTMLInputElement>): void => {
    this.props.login[e.currentTarget.name] = e.currentTarget.value
}

15
Was ist ein guter Ort, um über alle gängigen Ereignistypen zu lesen? Kann nirgendwo finden.
— r.sendecky

3
Ereignistypen reagieren? Sie werden alle auf der Ereignisseite in den Dokumenten beschrieben .
— Nitzan Tomer

3
Ich erhalte 'Name' existiert nicht für Typ 'EventTarget & HTMLInputElements' (TS v2.4)
— Falieson

4
Dies gibt mir immer noch den folgenden Fehler. "Die Eigenschaft 'value' ist für den Typ 'EventTarget & HTMLInputElement' nicht vorhanden."
— Tomhughes

1
@CMCDragonkai Ich denke, das e.keyist nur ein Teil von Tastaturereignissen.
— Nitzan Tomer

29

Das Problem liegt nicht beim Ereignistyp, sondern darin, dass die EventTarget-Schnittstelle in Typoskript nur drei Methoden hat:

interface EventTarget {
    addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
    dispatchEvent(evt: Event): boolean;
    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}

interface SyntheticEvent {
    bubbles: boolean;
    cancelable: boolean;
    currentTarget: EventTarget;
    defaultPrevented: boolean;
    eventPhase: number;
    isTrusted: boolean;
    nativeEvent: Event;
    preventDefault(): void;
    stopPropagation(): void;
    target: EventTarget;
    timeStamp: Date;
    type: string;
}

So ist es richtig , dass nameund valueexistiert nicht auf Eventtarget. Sie müssen das Ziel mit den gewünschten Eigenschaften auf den spezifischen Elementtyp umwandeln. In diesem Fall wird es sein HTMLInputElement.

update = (e: React.SyntheticEvent): void => {
    let target = e.target as HTMLInputElement;
    this.props.login[target.name] = target.value;
}

Auch für Veranstaltungen statt React.SyntheticEvent, man kann ihnen auch geben , wie folgend: Event, MouseEvent, KeyboardEvent... etc, hängt von dem Anwendungsfall des Handlers.

Der beste Weg, um all diese Typdefinitionen zu sehen, besteht darin, die .d.ts-Dateien aus beiden Typoskripten auszuchecken und zu reagieren.

Weitere Erklärungen finden Sie auch unter folgendem Link: Warum ist Event.target kein Element in Typescript?


2
ps. Es sieht so aus, als ob meine Typdefinitionsdatei etwas veraltet ist, da die generische SyntheticEvent <T> -Schnittstelle nicht angezeigt wird. Die Antwort von Nitzan Tomer ist besser.
— Edwin

Ja, Nitzans Antwort scheint sauberer zu sein. Danke für die Mühe.
— r.sendecky

25

Um die Antworten von Nitzan und Edwin zu kombinieren, stellte ich fest, dass so etwas für mich funktioniert:

update = (e: React.FormEvent<EventTarget>): void => {
    let target = e.target as HTMLInputElement;
    this.props.login[target.name] = target.value;
}

1
this.props.login [Zielname] = Zielwert; ??? Ändern Sie die Requisiten: o
— Marwen Trabelsi

Kopieren Sie einfach die Zeile aus der ursprünglichen Frage, damit die Antwort für das OP sinnvoll ist.
— Cham

21

Ich denke, der einfachste Weg ist:

type InputEvent = React.ChangeEvent<HTMLInputElement>;
type ButtonEvent = React.MouseEvent<HTMLButtonElement>;

update = (e: InputEvent): void => this.props.login[e.target.name] = e.target.value;
submit = (e:  ButtonEvent): void => {
    this.props.login.logIn();
    e.preventDefault();
}

Das hat es für mich getan.
— Benyam Ephrem

1
.ChangeEventwar der Schlüssel für mich
— Skyy2010

3

Sie können dies in Reaktion tun

handleEvent = (e: React.SyntheticEvent<EventTarget>) => {
  const simpleInput = (e.target as HTMLInputElement).value;
  //for simple html input values
  const formInput = (e.target as HTMLFormElement).files[0];
  //for html form elements
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.