216 votes

Typescript: types d'événements React

Quel est le type correct pour Réagir à des événements. Au départ, j'ai juste utilisé any pour des raisons de simplicité. Maintenant, je suis en train de nettoyer les choses et d'éviter l'utilisation de any complètement.

Ainsi, dans un simple formulaire comme ceci:

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 être travail que j'obtiens une erreur que name et value n'existent pas sur target.

Généralisée de la réponse pour tous les événements serait vraiment apprécié.

Merci

264voto

Nitzan Tomer Points 11798

Le SyntheticEvent interface est générique:

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

Et l' currentTarget est une intersection de la contrainte générique et EventTarget.
Aussi, étant donné que vos événements sont causés par un élément de saisie, vous devez utiliser l' FormEvent (dans le fichier de définition, la réagir docs).

Devrait être:

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

50voto

Edwin Points 436

Le problème n'est pas avec le type d'Événement, mais que le EventTarget interface en caractères d'imprimerie a seulement 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;
}

Donc, il est exact qu' name et value n'existent pas sur EventTarget. Ce que vous devez faire est de jeter la cible à la spécificité de ce type d'élément avec les propriétés dont vous avez besoin. Dans ce cas, il sera HTMLInputElement.

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

Également pour les événements au lieu de Réagir.SyntheticEvent, vous pouvez également taper 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 à la caisse de la .d.ts fichiers à partir de deux caractères d'imprimerie & de réagir.

Également consulter le lien suivant pour plus d'explications: Pourquoi est-Événement.l'objectif n'est pas de l'Élément en caractères d'imprimerie?

41voto

cham Points 611

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;
}
 

32voto

Serg The Bright Points 31

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();
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X