Ketikan: Jenis acara React


131

Apa tipe yang benar untuk event React. Awalnya saya hanya menggunakannya anydemi kesederhanaan. Sekarang, saya mencoba untuk membersihkan semuanya dan menghindari penggunaan anysepenuhnya.

Jadi dalam bentuk yang sederhana seperti ini:

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

Jenis apa yang saya gunakan di sini sebagai jenis acara?

React.SyntheticEvent<EventTarget>sepertinya tidak berfungsi karena saya mendapatkan kesalahan itu namedan valuetidak ada target.

Jawaban yang lebih umum untuk semua acara akan sangat dihargai.

Terima kasih

Jawaban:


146

The SyntheticEvent antarmuka generik:

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

Dan itu currentTargetadalah perpotongan dari batasan umum dan EventTarget.
Selain itu, karena kejadian Anda disebabkan oleh elemen masukan, Anda harus menggunakan FormEvent( dalam file definisi , dokumen react ).

Seharusnya:

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

15
Di mana tempat yang bagus untuk membaca tentang semua jenis acara umum? Tidak dapat menemukan di mana pun.
r.sendecky

3
Jenis acara React? Semuanya dijelaskan di halaman acara di dokumen .
Nitzan Tomer

3
Saya mendapatkan 'nama' tidak ada pada jenis 'EventTarget & HTMLInputElements' (TS v2.4)
Falieson

4
Ini masih memberi saya kesalahan berikut. "Nilai 'properti' tidak ada di jenis 'EventTarget & HTMLInputElement'."
tomhughes

1
@CMCDragonkai Saya rasa itu e.keyhanya bagian dari acara keyboard.
Nitzan Tomer

32

Masalahnya bukan pada tipe Peristiwa, tetapi antarmuka EventTarget di skrip tipe hanya memiliki 3 metode:

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

Jadi itu benar namedan valuetidak ada di EventTarget. Yang perlu Anda lakukan adalah mentransmisikan target ke jenis elemen tertentu dengan properti yang Anda butuhkan. Dalam hal ini akan terjadi HTMLInputElement.

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

Juga untuk acara bukannya React.SyntheticEvent, Anda juga dapat mengetik mereka sebagai berikut: Event, MouseEvent, KeyboardEvent... dll, tergantung pada kasus penggunaan pawang.

Cara terbaik untuk melihat semua definisi tipe ini adalah dengan memeriksa file .d.ts dari kedua skrip & react.

Lihat juga tautan berikut untuk penjelasan lebih lanjut: Mengapa Event.target bukan Elemen di Skrip Ketik?


2
ps. Sepertinya file definisi tipe saya agak ketinggalan jaman karena tidak menampilkan antarmuka <T> SyntheticEvent generik. Jawaban dari Nitzan Tomer lebih baik.
Edwin

Ya, jawaban Nitzan sepertinya lebih bersih. Terima kasih atas usahanya.
r.sendecky

26

Untuk menggabungkan jawaban Nitzan dan Edwin, saya menemukan bahwa sesuatu seperti ini berhasil untuk saya:

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

1
this.props.login [target.name] = target.value; ??? apakah Anda mengubah alat peraga: o
Marwen Trabelsi

Hanya menyalin baris dari pertanyaan awal agar jawabannya masuk akal bagi OP.
cham

21

Menurut saya cara yang paling sederhana adalah:

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

Ini berhasil untuk saya.
Benyam Ephrem

1
.ChangeEventadalah kuncinya bagi saya
Skyy2010

4

Anda dapat melakukan seperti ini dalam bereaksi

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
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.