Was ist der richtige Typ für React-Ereignisse. Ursprünglich habe ich nur any
der Einfachheit halber verwendet. Jetzt versuche ich, die Dinge aufzuräumen und die Verwendung von "any" vollstä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 soll ich hier als Ereignistyp verwenden?
React.SyntheticEventscheint nicht zu funktionieren, da ich eine Fehlermeldung erhalte, dass
Nameund
Wertnicht auf
Target` existieren.
Für eine allgemeinere Antwort für alle Ereignisse wäre ich sehr dankbar.
Vielen Dank
Die Schnittstelle SyntheticEvent ist generisch:
interface SyntheticEvent<T> {
...
currentTarget: EventTarget & T;
...
}
Und das currentTarget
ist eine Schnittmenge aus der generischen Einschränkung und EventTarget
.
Da Ihre Ereignisse durch ein Eingabeelement ausgelöst werden, sollten Sie das FormEvent
verwenden (in der Definitionsdatei, in den React-Dokumenten).
Sollte sein:
update = (e: React.FormEvent<HTMLInputElement>): void => {
this.props.login[e.currentTarget.name] = e.currentTarget.value
}
Das Problem liegt nicht am Typ Event, sondern daran, dass die EventTarget-Schnittstelle in Typescript nur 3 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;
}
Es ist also richtig, dass Name
und Wert
bei EventTarget nicht existieren. Was Sie tun müssen, ist, das Target auf den spezifischen Elementtyp mit den benötigten Eigenschaften zu casten. In diesem Fall wird es HTMLInputElement
sein.
update = (e: React.SyntheticEvent): void => {
let target = e.target as HTMLInputElement;
this.props.login[target.name] = target.value;
}
Auch für Ereignisse anstelle von React.SyntheticEvent, können Sie sie wie folgt eingeben: Event
, MouseEvent
, KeyboardEvent
...etc, abhängig vom Anwendungsfall des Handlers.
Der beste Weg, um all diese Typdefinitionen zu sehen, ist, die .d.ts-Dateien von beiden typescript & react auszuchecken.
Weitere Erklärungen finden Sie auch unter folgendem Link: https://stackoverflow.com/questions/28900077/why-is-event-target-not-element-in-typescript
Um die Antworten von Nitzan und Edwin zu kombinieren, habe ich herausgefunden, 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;
}