Quel est le type correct pour les événements React. Au début, je viens d'utiliser any
pour des raisons de simplicité. Maintenant, j'essaie de nettoyer les choses et d'éviter l'utilisation de any
complètement.
Donc, sous une forme simple comme celle-ci:
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>
)
}
}
Quel type dois-je utiliser ici comme type d'événement?
React.SyntheticEvent<EventTarget>
ne semble pas fonctionner car je reçois une erreur indiquant que name
et value
n'existent pas sur target
.
Une réponse plus généralisée pour tous les événements serait vraiment appréciée.
Merci
L’interface SyntheticEvent est générique:
interface SyntheticEvent<T> {
...
currentTarget: EventTarget & T;
...
}
Et le currentTarget
est une intersection de la contrainte générique et EventTarget
.
De plus, comme vos événements sont causés par un élément d’entrée, vous devez utiliser le paramètre FormEvent
( dans le fichier de définition , les documents de réaction ).
Devrait être:
update = (e: React.FormEvent<HTMLInputElement>): void => {
this.props.login[e.currentTarget.name] = e.currentTarget.value
}
Le problème ne vient pas du type Event, mais du fait que l'interface EventTarget dans TypeScript ne comporte que 3 méthodes:
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;
}
Il est donc correct que name
et value
n'existent pas sur EventTarget. Ce que vous devez faire est de convertir la cible en un type d'élément spécifique avec les propriétés dont vous avez besoin. Dans ce cas, il s'agira de HTMLInputElement
.
update = (e: React.SyntheticEvent): void => {
let target = e.target as HTMLInputElement;
this.props.login[target.name] = target.value;
}
De même, pour les événements au lieu de React.SyntheticEvent, vous pouvez également les saisir comme suit: Event
, MouseEvent
, KeyboardEvent
... etc., dépend du cas d'utilisation du gestionnaire.
Le meilleur moyen de voir toutes ces définitions de type est d'extraire les fichiers .d.ts de TypeScript & react.
Consultez également le lien suivant pour plus d'explications: Pourquoi Event.target n'est-il pas un élément dans Typescript?
Pour combiner les réponses de Nitzan et d'Edwin, j'ai trouvé que quelque chose comme cela fonctionnait pour moi:
update = (e: React.FormEvent<EventTarget>): void => {
let target = e.target as HTMLInputElement;
this.props.login[target.name] = target.value;
}
Je pense que le moyen le plus simple est que:
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();
}