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

r.sendecky
quelle

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
}
Nitzan Tomer
quelle
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?

Edwin
quelle
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;
}
cham
quelle
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();
}
Serg The Bright
quelle
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
}
Chandan Kumar
quelle